diff options
Diffstat (limited to 'indra')
121 files changed, 2074 insertions, 1498 deletions
| diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 8efad33f71..de81512eef 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -61,6 +61,7 @@ if(WINDOWS)          nghttp2.dll          glod.dll          libhunspell.dll +        uriparser.dll          )      # Filenames are different for 32/64 bit BugSplat file and we don't @@ -165,6 +166,9 @@ elseif(DARWIN)          libnghttp2.dylib          libnghttp2.14.dylib          libnghttp2.14.19.0.dylib +        liburiparser.dylib +        liburiparser.1.dylib +        liburiparser.1.0.27.dylib         )      if (FMODSTUDIO) diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake index de146885a0..ecc5b74ef1 100644 --- a/indra/cmake/URIPARSER.cmake +++ b/indra/cmake/URIPARSER.cmake @@ -29,7 +29,7 @@ else (USESYSTEMLIBS)      set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive)      set(URIPARSER_LIBRARIES uriparser)    elseif (DARWIN) -    set(URIPARSER_LIBRARIES uriparser) +    set(URIPARSER_LIBRARIES liburiparser.dylib)    endif (WINDOWS)    set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser)  endif (USESYSTEMLIBS) diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 262929006d..23419a52a7 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -56,10 +56,6 @@  #include "stringize.h"  #include "llexception.h" -#if LL_WINDOWS -#include <excpt.h> -#endif -  // static  LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)  { @@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl  #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ -    if (code == STATUS_MSC_EXCEPTION) -    { -        // C++ exception, go on -        return EXCEPTION_CONTINUE_SEARCH; -    } -    else -    { -        // handle it -        return EXCEPTION_EXECUTE_HANDLER; -    } -} -  void LLCoros::winlevel(const callable_t& callable)  {      __try      {          callable();      } -    __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) +    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))      {          // convert to C++ styled exception          // Note: it might be better to use _se_set_translator diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 5ce8958687..b584b0ff8b 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -24,11 +24,14 @@  // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if  // _Unwind_Backtrace is available without `_GNU_SOURCE`."  #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED +  #if LL_WINDOWS  // On Windows, header-only implementation causes macro collisions -- use  // prebuilt library  #define BOOST_STACKTRACE_LINK +#include <excpt.h>  #endif // LL_WINDOWS +  #include <boost/stacktrace.hpp>  // other Linden headers  #include "llerror.h" @@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc)      // Anyway, which of us is really going to examine more than 100 frames?      exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100));  } + +#if LL_WINDOWS + +// For windows SEH exception handling we sometimes need a filter that will +// separate C++ exceptions from C SEH exceptions +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ +    if (code == STATUS_MSC_EXCEPTION) +    { +        // C++ exception, go on +        return EXCEPTION_CONTINUE_SEARCH; +    } +    else +    { +        // handle it +        return EXCEPTION_EXECUTE_HANDLER; +    } +} + +#endif //LL_WINDOWS diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 422dd8810a..375bea4a57 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str       log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT)  void log_unhandled_exception_(const char*, int, const char*, const std::string&); + +#if LL_WINDOWS + +// SEH exception filtering for use in __try __except +// Separates C++ exceptions from C SEH exceptions +// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); + +#endif //LL_WINDOWS +  #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 83a4b64e8f..ad933154c2 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -388,7 +388,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()      // extracts just the first (key) element from each sorted_iterator, then      // uses vec_t's range constructor... but frankly this is more      // straightforward, as long as we remember the above reserve() call! -    for (const SingletonDeps::sorted_iterator::value_type& pair : sdeps.sort()) +    for (const SingletonDeps::sorted_iterator::value_type pair : sdeps.sort())      {          ret.push_back(pair.first);      } diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index c275b90120..e4f229dd16 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -29,10 +29,13 @@  #include "linden_common.h"  #include "lluriparser.h" +#if LL_DARWIN +#include <signal.h> +#include <setjmp.h> +#endif +  LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)  { -	mState.uri = &mUri; -  	if (u.find("://") == std::string::npos)  	{  		mNormalizedUri = "http://"; @@ -51,7 +54,7 @@ LLUriParser::~LLUriParser()  S32 LLUriParser::parse()  { -	mRes = uriParseUriA(&mState, mNormalizedUri.c_str()); +	mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);  	return mRes;  } @@ -158,31 +161,69 @@ void LLUriParser::extractParts()  	}  } +#if LL_DARWIN +typedef void(*sighandler_t)(int); +jmp_buf return_to_normalize; +void uri_signal_handler(int signal) +{ +    // Apparently signal handler throwing an exception doesn't work. +    // This is ugly and unsafe due to not unwinding content of uriparser library, +    // but unless we have a way to catch this as NSexception, jump appears to be the only option. +    longjmp(return_to_normalize, 1 /*setjmp will return this value*/); +} +#endif +  S32 LLUriParser::normalize()  {  	mNormalizedTmp = mTmpScheme;  	if (!mRes)  	{ -		mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); - -		if (!mRes) -		{ -			S32 chars_required; -			mRes = uriToStringCharsRequiredA(&mUri, &chars_required); - -			if (!mRes) -			{ -				chars_required++; -				std::vector<char> label_buf(chars_required); -				mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); - -				if (!mRes) -				{ -					mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; -					mTmpScheme = false; -				} -			} -		} +#if LL_DARWIN +        sighandler_t last_handler; +        last_handler = signal(SIGILL, &uri_signal_handler);		// illegal instruction +        if (setjmp(return_to_normalize)) +        { +            // Issue: external library crashed via signal +            // If you encountered this, please try to figure out what's wrong: +            // 1. Verify that library's input is 'sane' +            // 2. Check if we have an NSexception to work with (unlikely) +            // 3. See if passing same string causes exception to repeat +            // +            // Crash happens at uriNormalizeSyntaxExA +            // Warning!!! This does not properly unwind stack, +            // if this can be handled by NSexception, it needs to be remade +            llassert(0); + +            LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL; +            signal(SIGILL, last_handler); +            return 1; +        } +#endif + +        mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); + +#if LL_DARWIN +        signal(SIGILL, last_handler); +#endif + +        if (!mRes) +        { +            S32 chars_required; +            mRes = uriToStringCharsRequiredA(&mUri, &chars_required); + +            if (!mRes) +            { +                chars_required++; +                std::vector<char> label_buf(chars_required); +                mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); + +                if (!mRes) +                { +                    mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; +                    mTmpScheme = false; +                } +            } +        }  	}  	if(mTmpScheme) diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h index cfbf54f3c8..92626b9054 100644 --- a/indra/llcommon/lluriparser.h +++ b/indra/llcommon/lluriparser.h @@ -76,7 +76,6 @@ private:  	std::string mFragment;  	std::string mNormalizedUri; -	UriParserStateA mState;  	UriUriA mUri;  	S32 mRes; diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 11b2e3e929..240ea2da83 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -178,6 +178,7 @@ if (DARWIN)      libaprutil-1.0.dylib      libexception_handler.dylib      libnghttp2*.dylib +    liburiparser*.dylib      ${EXPAT_COPY}      ) diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index e0f22f1160..274e6a50ad 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -255,7 +255,7 @@ public:      virtual void logAssetStorageInfo() = 0; -	void checkForTimeouts(); +	virtual void checkForTimeouts();  	void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,  									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 7380df041d..c67f59bc0c 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -145,10 +145,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU      }      LLSD httpResults; +    bool success = true;      try      { -        bool success = true;          LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);          LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url); @@ -163,35 +163,47 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU          else          {              httpResults = results["http_result"]; -            success = httpResults["success"].asBoolean(); -            if (!success) +            if (!httpResults.isMap())              { -                LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code " -                    << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL; +                success = false; +                LL_WARNS("AvNameCache") << " Invalid http_result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL;              } -        } - -        if (!success) -        {   // on any sort of failure add dummy records for any agent IDs  -            // in this request that we do not have cached already -            std::vector<LLUUID>::const_iterator it = agentIds.begin(); -            for ( ; it != agentIds.end(); ++it) +            else              { -                const LLUUID& agent_id = *it; -                LLAvatarNameCache::getInstance()->handleAgentError(agent_id); +                success = httpResults["success"].asBoolean(); +                if (!success) +                { +                    LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code " +                        << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL; +                }              } -            return;          } -        LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); +        if (LLAvatarNameCache::instanceExists()) +        { +            if (!success) +            {   // on any sort of failure add dummy records for any agent IDs  +                // in this request that we do not have cached already +                std::vector<LLUUID>::const_iterator it = agentIds.begin(); +                for (; it != agentIds.end(); ++it) +                { +                    const LLUUID& agent_id = *it; +                    LLAvatarNameCache::getInstance()->handleAgentError(agent_id); +                } +                return; +            } +            LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); +        }      }      catch (...)      {          LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() -                                          << "('" << url << "', " << agentIds.size() -                                          << " http result: " << httpResults.asString() -                                          << " Agent Ids)")); +                                          << "('" << url << "', " +                                          << agentIds.size() << "Agent Ids," +                                          << " http result: " << S32(success) +                                          << " has response: " << S32(httpResults.size()) +                                          << ")"));          throw;      }  } diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index a4fe3a2a8e..4d76dacdf7 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -47,7 +47,7 @@ static const std::map<std::string, U32> DefaultPoolSizes{  };  static const U32 DEFAULT_POOL_SIZE = 5; -static const U32 DEFAULT_QUEUE_SIZE = 4096; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096;  //=========================================================================  class LLCoprocedurePool: private boost::noncopyable @@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd      mPropertyDefineFn = updatefn;      // workaround until we get mutex into initializePool -    initializePool("VAssetStorage"); +    initializePool("AssetStorage");      initializePool("Upload");  } @@ -281,7 +281,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):      mPoolSize(size),      mActiveCoprocsCount(0),      mPending(0), -    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(DEFAULT_QUEUE_SIZE)), +    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),      mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),      mCoroMapping()  { @@ -332,7 +332,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):          mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));      } -    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL; +    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;  }  LLCoprocedurePool::~LLCoprocedurePool()  diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 70204ba02b..d5557c129f 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -91,6 +91,9 @@ private:      SettingQuery_t mPropertyQueryFn;      SettingUpdate_t mPropertyDefineFn; + +public: +    static const U32 DEFAULT_QUEUE_SIZE;  };  #endif diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a219ac1450..a1bfc4edd9 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -28,6 +28,8 @@  #include "llmaterial.h" +#include "../llrender/llglheaders.h" +  /**   * Materials cap parameters   */ @@ -105,6 +107,8 @@ LLMaterial::LLMaterial()      , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)      , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)      , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) +    , mDiffuseFormatPrimary(GL_RGBA) +    , mDiffuseBaked(false)      , mAlphaMaskCutoff(0)  {  } @@ -311,6 +315,20 @@ void LLMaterial::setEnvironmentIntensity(U8 intensity)      mEnvironmentIntensity = intensity;  } +U8 LLMaterial::getDiffuseAlphaModeRender() const +{ +    if (mDiffuseBaked +        || mDiffuseFormatPrimary == GL_RGBA +        || mDiffuseFormatPrimary == GL_ALPHA) +    { +        return mDiffuseAlphaMode; +    } +    else +    { +        return DIFFUSE_ALPHA_MODE_NONE; +    } +} +  U8 LLMaterial::getDiffuseAlphaMode() const  {      return mDiffuseAlphaMode; @@ -321,6 +339,26 @@ void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode)      mDiffuseAlphaMode = alpha_mode;  } +U32 LLMaterial::getDiffuseFormatPrimary() const +{ +    return mDiffuseFormatPrimary; +} + +void LLMaterial::setDiffuseFormatPrimary(U32 format_primary) +{ +    mDiffuseFormatPrimary = format_primary; +} + +bool LLMaterial::getIsDiffuseBaked() const +{ +    return mDiffuseBaked; +} + +void LLMaterial::setDiffuseBaked(bool baked) +{ +    mDiffuseBaked = baked; +} +  U8 LLMaterial::getAlphaMaskCutoff() const  {      return mAlphaMaskCutoff; @@ -437,7 +475,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)      }      else      { -        ret = getDiffuseAlphaMode(); +        ret = getDiffuseAlphaModeRender();      }      llassert(ret < SHADER_COUNT); diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index d58b7ee812..1207917568 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -115,8 +115,17 @@ public:      void        setSpecularLightExponent(U8 exponent);      U8          getEnvironmentIntensity() const;      void        setEnvironmentIntensity(U8 intensity); + +    // getDiffuseAlphaModeRender takes into account if image supports alpha +    // and returns value apropriate for render +    // getDiffuseAlphaMode() returns value as is +    U8          getDiffuseAlphaModeRender() const;      U8          getDiffuseAlphaMode() const;      void        setDiffuseAlphaMode(U8 alpha_mode); +    U32         getDiffuseFormatPrimary() const; +    void        setDiffuseFormatPrimary(U32 format_primary); +    bool        getIsDiffuseBaked() const; +    void        setDiffuseBaked(bool baked);      U8          getAlphaMaskCutoff() const;      void        setAlphaMaskCutoff(U8 cutoff); @@ -147,6 +156,8 @@ protected:      U8          mSpecularLightExponent;      U8          mEnvironmentIntensity;      U8          mDiffuseAlphaMode; +    U32         mDiffuseFormatPrimary; // value from texture, LLGLenum, is not included in fromLLSD/asLLSD +    bool        mDiffuseBaked; // is not included in fromLLSD/asLLSD      U8          mAlphaMaskCutoff;  }; diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 6a51c4240b..08da599ef2 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -187,10 +187,32 @@ void LLCheckBoxCtrl::clear()  void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  { -	S32 label_top = mLabel->getRect().mTop; -	mLabel->reshapeToFitText(); +    LLRect rect = getRect(); +    S32 delta_width = width - rect.getWidth(); +    S32 delta_height = height - rect.getHeight(); -	LLRect label_rect = mLabel->getRect(); +    if (delta_width || delta_height) +    { +        // adjust our rectangle +        rect.mRight = getRect().mLeft + width; +        rect.mTop = getRect().mBottom + height; +        setRect(rect); +    } + +    // reshapeToFitText reshapes label to minimal size according to last bounding box +    // it will work fine in case of decrease of space, but if we get more space or text +    // becomes longer, label will fail to grow so reinit label's dimentions. +     +    static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); +    LLRect label_rect = mLabel->getRect(); +    S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; +    label_rect.mRight = label_rect.mLeft + new_width; +    mLabel->setRect(label_rect); + +	S32 label_top = label_rect.mTop; +	mLabel->reshapeToFitText(TRUE); + +    label_rect = mLabel->getRect();  	if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN)  	{  		// reshapeToFitText uses LLView::reshape() which always reshapes @@ -210,6 +232,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  		llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),  		llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));  	mButton->setShape(btn_rect); + +    updateBoundingRect();  }  //virtual diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index f4ddfa8f18..e62b2779dd 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -204,6 +204,7 @@ public:  	virtual bool hasChildren() const = 0;  	virtual void addChild(LLFolderViewModelItem* child) = 0;  	virtual void removeChild(LLFolderViewModelItem* child) = 0; +	virtual void clearChildren() = 0;  	// This method will be called to determine if a drop can be  	// performed, and will set drop to TRUE if a drop is @@ -301,9 +302,8 @@ public:  	virtual void clearChildren()  	{ -		// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects -		// This is different and not equivalent to calling removeChild() on each child -		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); +		// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest +		std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });  		mChildren.clear();  		dirtyDescendantsFilter();  		dirtyFilter(); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 4aae1e374b..29a156e933 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -166,7 +166,7 @@ void LLLayoutPanel::setVisible( BOOL visible )  void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ )  { -	if (width == getRect().getWidth() && height == getRect().getHeight()) return; +	if (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return;  	if (!mIgnoreReshape && mAutoResize == false)  	{ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 5568a84494..2c28b7943e 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3244,7 +3244,7 @@ void hide_top_view( LLView* view )  // x and y are the desired location for the popup, in the spawning_view's  // coordinate frame, NOT necessarily the mouse location  // static -void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) +void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x, S32 mouse_y)  {  	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size  	const S32 CURSOR_WIDTH = 12; @@ -3275,12 +3275,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)  		}  	} -	// Save click point for detecting cursor moves before mouse-up. -	// Must be in local coords to compare with mouseUp events. -	// If the mouse doesn't move, the menu will stay open ala the Mac. -	// See also LLContextMenu::show() -	S32 mouse_x, mouse_y; -  	// Resetting scrolling position  	if (menu->isScrollable() && menu->isScrollPositionOnShowReset())  	{ @@ -3291,7 +3285,18 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)  	menu->needsArrange();  	menu->arrangeAndClear(); -	LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); +	if ((mouse_x == 0) || (mouse_y == 0)) + +	{ +		// Save click point for detecting cursor moves before mouse-up. +		// Must be in local coords to compare with mouseUp events. +		// If the mouse doesn't move, the menu will stay open ala the Mac. +		// See also LLContextMenu::show() + +		LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); +	} +	 +	  	LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);  	const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect(); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 1f11f26192..805620bf9b 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -510,7 +510,7 @@ public:  	void createJumpKeys();  	// Show popup at a specific location, in the spawn_view's coordinate frame -	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y); +	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x = 0, S32 mouse_y = 0);  	// Whether to drop shadow menu bar   	void setDropShadowed( const BOOL shadowed ); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ff72417867..20bea7fe24 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1179,7 +1179,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask)  void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent)  { -	if (width != getRect().getWidth() || height != getRect().getHeight()) +	if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape)  	{  		bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 0afd32f332..134afc005b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -163,13 +163,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text  } -void LLTextBox::reshapeToFitText() +void LLTextBox::reshapeToFitText(BOOL called_from_parent)  {  	reflow();  	S32 width = getTextPixelWidth();  	S32 height = getTextPixelHeight(); -	reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE ); +	reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent );  } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 061d2dd23d..c3e3b61912 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -60,7 +60,7 @@ public:  	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }  	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ); -	void			reshapeToFitText(); +	void			reshapeToFitText(BOOL called_from_parent = FALSE);  	S32				getTextPixelWidth();  	S32				getTextPixelHeight(); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index a69c0eb008..20dda54771 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -517,8 +517,7 @@ LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()  // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  // -LLUrlEntryAgent::LLUrlEntryAgent() : -	mAvatarNameCacheConnection() +LLUrlEntryAgent::LLUrlEntryAgent()  {  	mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",  							boost::regex::perl|boost::regex::icase); @@ -549,7 +548,15 @@ void LLUrlEntryAgent::callObservers(const std::string &id,  void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,  										const LLAvatarName& av_name)  { -	mAvatarNameCacheConnection.disconnect(); +	avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); +	if (it != mAvatarNameCacheConnections.end()) +	{ +		if (it->second.connected()) +		{ +			it->second.disconnect(); +		} +		mAvatarNameCacheConnections.erase(it); +	}   	std::string label = av_name.getCompleteName(); @@ -636,11 +643,17 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa  	}  	else  	{ -		if (mAvatarNameCacheConnection.connected()) +		avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); +		if (it != mAvatarNameCacheConnections.end())  		{ -			mAvatarNameCacheConnection.disconnect(); +			if (it->second.connected()) +			{ +				it->second.disconnect(); +			} +			mAvatarNameCacheConnections.erase(it);  		} -		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); +		mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); +  		addObserver(agent_id_string, url, cb);  		return LLTrans::getString("LoadingData");  	} @@ -701,14 +714,21 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)  // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)  // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)  // -LLUrlEntryAgentName::LLUrlEntryAgentName() : -	mAvatarNameCacheConnection() +LLUrlEntryAgentName::LLUrlEntryAgentName()  {}  void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,  										const LLAvatarName& av_name)  { -	mAvatarNameCacheConnection.disconnect(); +	avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); +	if (it != mAvatarNameCacheConnections.end()) +	{ +		if (it->second.connected()) +		{ +			it->second.disconnect(); +		} +		mAvatarNameCacheConnections.erase(it); +	}  	std::string label = getName(av_name);  	// received the agent name from the server - tell our observers @@ -743,11 +763,17 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab  	}  	else  	{ -		if (mAvatarNameCacheConnection.connected()) +		avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); +		if (it != mAvatarNameCacheConnections.end())  		{ -			mAvatarNameCacheConnection.disconnect(); +			if (it->second.connected()) +			{ +				it->second.disconnect(); +			} +			mAvatarNameCacheConnections.erase(it);  		} -		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); +		mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); +  		addObserver(agent_id_string, url, cb);  		return LLTrans::getString("LoadingData");  	} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 0a0c247a6a..4af1ab5096 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -212,10 +212,14 @@ public:  	LLUrlEntryAgent();  	~LLUrlEntryAgent()  	{ -		if (mAvatarNameCacheConnection.connected()) +		for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)  		{ -			mAvatarNameCacheConnection.disconnect(); +			if (it->second.connected()) +			{ +				it->second.disconnect(); +			}  		} +		mAvatarNameCacheConnections.clear();  	}  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);  	/*virtual*/ std::string getIcon(const std::string &url); @@ -227,7 +231,9 @@ protected:  	/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);  private:  	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); -	boost::signals2::connection mAvatarNameCacheConnection; + +	typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t; +	avatar_name_cache_connection_map_t mAvatarNameCacheConnections;  };  /// @@ -241,10 +247,14 @@ public:  	LLUrlEntryAgentName();  	~LLUrlEntryAgentName()  	{ -		if (mAvatarNameCacheConnection.connected()) +		for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)  		{ -			mAvatarNameCacheConnection.disconnect(); +			if (it->second.connected()) +			{ +				it->second.disconnect(); +			}  		} +		mAvatarNameCacheConnections.clear();  	}  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);  	/*virtual*/ LLStyle::Params getStyle() const; @@ -253,7 +263,9 @@ protected:  	virtual std::string getName(const LLAvatarName& avatar_name) = 0;  private:  	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); -	boost::signals2::connection mAvatarNameCacheConnection; + +	typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t; +	avatar_name_cache_connection_map_t mAvatarNameCacheConnections;  }; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index e3a6a98a9f..cd47e2ecea 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1402,7 +1402,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)  			S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;  			S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;  			viewp->translate( delta_x, delta_y ); -			if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) +			if (child_rect.getWidth() != viewp->getRect().getWidth() +                || child_rect.getHeight() != viewp->getRect().getHeight() +                || sForceReshape)  			{  				viewp->reshape(child_rect.getWidth(), child_rect.getHeight());  			} diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index d77997a928..30bc743e72 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -263,6 +263,18 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()  #endif  } +// static +std::vector<std::string> LLWindow::getDisplaysResolutionList() +{ +#if LL_WINDOWS +	return LLWindowWin32::getDisplaysResolutionList(); +#elif LL_DARWIN +	return LLWindowMacOSX::getDisplaysResolutionList(); +#else +	return std::vector<std::string>(); +#endif +} +  #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)  #define UTF16_IS_LOW_SURROGATE(U)  ((U16)((U) - 0xDC00) < 0x0400)  #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index f1113acd5f..d4d5b76937 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -169,6 +169,8 @@ public:  	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)  	virtual F32 getSystemUISize() { return 1.0; } +	static std::vector<std::string> getDisplaysResolutionList(); +      // windows only DirectInput8 for joysticks      virtual void* getDirectInput8() { return NULL; };      virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; }; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2604a23c85..0d0607a0bb 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -41,6 +41,7 @@  #include <OpenGL/OpenGL.h>  #include <Carbon/Carbon.h>  #include <CoreServices/CoreServices.h> +#include <CoreGraphics/CGDisplayConfiguration.h>  extern BOOL gDebugWindowProc;  BOOL gHiDPISupport = TRUE; @@ -1911,6 +1912,35 @@ void LLWindowMacOSX::interruptLanguageTextInput()  	commitCurrentPreedit(mGLView);  } +std::vector<std::string> LLWindowMacOSX::getDisplaysResolutionList() +{ +	std::vector<std::string> resolution_list; +	 +	CGDirectDisplayID display_ids[10]; +	uint32_t found_displays = 0; +	CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays); +	 +	if (kCGErrorSuccess != err) +	{ +		LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL; +		return std::vector<std::string>(); +	} +	 +	for (uint32_t i = 0; i < found_displays; i++) +	{ +		S32 monitor_width = CGDisplayPixelsWide(display_ids[i]); +		S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]); +		 +		std::ostringstream sstream; +		sstream << monitor_width << "x" << monitor_height;; +		std::string res = sstream.str(); +		 +		resolution_list.push_back(res); +	} +	 +	return resolution_list; +} +  //static  std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()  { diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 24651027e8..bf45238c8d 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -114,6 +114,8 @@ public:  	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);  	/*virtual*/ F32 getSystemUISize(); +	static std::vector<std::string> getDisplaysResolutionList(); +  	static std::vector<std::string> getDynamicFallbackFontList();  	// Provide native key event data diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index e8abb9f31a..f774cd0d31 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@  // Linden library includes  #include "llerror.h" +#include "llexception.h"  #include "llfasttimer.h"  #include "llgl.h"  #include "llstring.h" @@ -121,7 +122,7 @@ void show_window_creation_error(const std::string& title)  	LL_WARNS("Window") << title << LL_ENDL;  } -HGLRC SafeCreateContext(HDC hdc) +HGLRC SafeCreateContext(HDC &hdc)  {  	__try   	{ @@ -133,6 +134,22 @@ HGLRC SafeCreateContext(HDC hdc)  	}  } +GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ +    __try +    { +        return ChoosePixelFormat(hdc, ppfd); +    } +    __except (EXCEPTION_EXECUTE_HANDLER) +    { +        // convert to C++ styled exception +        // C exception don't allow classes, so it's a regular char array +        char integer_string[32]; +        sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); +        throw std::exception(integer_string); +    } +} +  //static  BOOL LLWindowWin32::sIsClassRegistered = FALSE; @@ -404,6 +421,39 @@ LLWinImm::~LLWinImm()  } +class LLMonitorInfo +{ +public: + +	std::vector<std::string> getResolutionsList() { return mResList; } + +	LLMonitorInfo() +	{ +		EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); +	} + +private: + +	static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData) +	{ +		int monitor_width = lprcMonitor->right - lprcMonitor->left; +		int monitor_height = lprcMonitor->bottom - lprcMonitor->top; +		 +		std::ostringstream sstream; +		sstream << monitor_width << "x" << monitor_height;; +		std::string res = sstream.str(); + +		LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData); +		pThis->mResList.push_back(res); + +		return TRUE; +	} + +	std::vector<std::string> mResList; +}; + +static LLMonitorInfo sMonitorInfo; +  LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  							 const std::string& title, const std::string& name, S32 x, S32 y, S32 width,  							 S32 height, U32 flags,  @@ -432,7 +482,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  	memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp));  	memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp));  	mCustomGammaSet = FALSE; -	 +	mWindowHandle = NULL; +  	if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))  	{  		mMouseVanish = TRUE; @@ -1157,7 +1208,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO          << " Height: " << (window_rect.bottom - window_rect.top)          << " Fullscreen: " << mFullscreen          << LL_ENDL; -    if (!destroy_window_handler(mWindowHandle)) +    if (mWindowHandle && !destroy_window_handler(mWindowHandle))      {          LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;      }	 @@ -1216,13 +1267,26 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO  	LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; -	if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) -	{ -		close(); -		OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), -			mCallbacks->translateString("MBError"), OSMB_OK); -		return FALSE; -	} +    try +    { +        // Looks like ChoosePixelFormat can crash in case of faulty driver +        if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd))) +        { +            LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; +            OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), +                mCallbacks->translateString("MBError"), OSMB_OK); +            close(); +            return FALSE; +        } +    } +    catch (...) +    { +        LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); +        OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), +            mCallbacks->translateString("MBError"), OSMB_OK); +        close(); +        return FALSE; +    }  	LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; @@ -1482,7 +1546,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO  		}          // Destroy The Window -        if (!destroy_window_handler(mWindowHandle)) +        if (mWindowHandle && !destroy_window_handler(mWindowHandle))          {              LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;          }		 @@ -4288,6 +4352,12 @@ F32 LLWindowWin32::getSystemUISize()  }  //static +std::vector<std::string> LLWindowWin32::getDisplaysResolutionList() +{  +	return sMonitorInfo.getResolutionsList(); +} + +//static  std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()  {  	// Fonts previously in getFontListSans() have moved to fonts.xml. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index ee0df570e9..0b3d14fb16 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -114,6 +114,7 @@ public:  	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); +	static std::vector<std::string> getDisplaysResolutionList();  	static std::vector<std::string> getDynamicFallbackFontList();  	static void setDPIAwareness(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 82e6cda193..beaa277032 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -234,6 +234,7 @@ set(viewer_SOURCE_FILES      llfloaterconversationpreview.cpp      llfloaterdeleteprefpreset.cpp      llfloaterdestinations.cpp +    llfloatereditenvironmentbase.cpp      llfloatereditextdaycycle.cpp      llfloaterenvironmentadjust.cpp      llfloaterevent.cpp @@ -865,6 +866,7 @@ set(viewer_HEADER_FILES      llfloaterconversationpreview.h      llfloaterdeleteprefpreset.h      llfloaterdestinations.h +    llfloatereditenvironmentbase.h      llfloatereditextdaycycle.h      llfloaterenvironmentadjust.h      llfloaterevent.h @@ -1812,6 +1814,8 @@ if (WINDOWS)        ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll        ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll        ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll +      ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll +      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 393a38fb9c..dac473a025 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5946,7 +5946,7 @@        <key>Type</key>        <string>String</string>        <key>Value</key> -      <string>http://map.secondlife.com.s3.amazonaws.com/</string> +      <string>https://map.secondlife.com/</string>      </map>      <key>CurrentMapServerURL</key>      <map> @@ -15158,7 +15158,7 @@          <key>Value</key>              <real>1</real>          </map> -    <key>PoolSizeVAssetStorage</key> +    <key>PoolSizeAssetStorage</key>          <map>          <key>Comment</key>              <string>Coroutine Pool size for AssetStorage requests</string> diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icnsBinary files differ index e15e34140d..a30b51b67a 100644 --- a/indra/newview/icons/release/secondlife.icns +++ b/indra/newview/icons/release/secondlife.icns diff --git a/indra/newview/icons/release/secondlife.ico b/indra/newview/icons/release/secondlife.icoBinary files differ index 28bf1e7664..93d4fa54ba 100644 --- a/indra/newview/icons/release/secondlife.ico +++ b/indra/newview/icons/release/secondlife.ico diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.pngBinary files differ index 4c9544f498..2f21c1c7fc 100644 --- a/indra/newview/icons/release/secondlife_128.png +++ b/indra/newview/icons/release/secondlife_128.png diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.pngBinary files differ index bb3168b8be..68f1427309 100644 --- a/indra/newview/icons/release/secondlife_16.png +++ b/indra/newview/icons/release/secondlife_16.png diff --git a/indra/newview/icons/release/secondlife_256.BMP b/indra/newview/icons/release/secondlife_256.BMPBinary files differ index 74deedd7d3..dba2636803 100644 --- a/indra/newview/icons/release/secondlife_256.BMP +++ b/indra/newview/icons/release/secondlife_256.BMP diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.pngBinary files differ index bece338a90..8f324910e7 100644 --- a/indra/newview/icons/release/secondlife_256.png +++ b/indra/newview/icons/release/secondlife_256.png diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.pngBinary files differ index 736359c147..2b7cdef03d 100644 --- a/indra/newview/icons/release/secondlife_32.png +++ b/indra/newview/icons/release/secondlife_32.png diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.pngBinary files differ index 07d39ae585..c2ef372dd7 100644 --- a/indra/newview/icons/release/secondlife_48.png +++ b/indra/newview/icons/release/secondlife_48.png diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.pngBinary files differ index 53d1643f45..d8a0c2924d 100644 --- a/indra/newview/icons/release/secondlife_512.png +++ b/indra/newview/icons/release/secondlife_512.png diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMPBinary files differ index 09df573870..dba2636803 100644 --- a/indra/newview/installers/windows/install_icon.BMP +++ b/indra/newview/installers/windows/install_icon.BMP diff --git a/indra/newview/installers/windows/install_icon.ico b/indra/newview/installers/windows/install_icon.icoBinary files differ index efe6c4f323..93d4fa54ba 100644 --- a/indra/newview/installers/windows/install_icon.ico +++ b/indra/newview/installers/windows/install_icon.ico diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMPBinary files differ index 562b56676a..dba2636803 100644 --- a/indra/newview/installers/windows/uninstall_icon.BMP +++ b/indra/newview/installers/windows/uninstall_icon.BMP diff --git a/indra/newview/installers/windows/uninstall_icon.ico b/indra/newview/installers/windows/uninstall_icon.icoBinary files differ index 05e1546860..93d4fa54ba 100644 --- a/indra/newview/installers/windows/uninstall_icon.ico +++ b/indra/newview/installers/windows/uninstall_icon.ico diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index a2b7362608..3f1b5139c5 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -134,6 +134,7 @@  		// called again. Since it returned false, do not yet cancel  		// frameTimer.  		handleQuit(); +		[[NSApplication sharedApplication] stopModal];  		return NSTerminateCancel;  	} else {  		// pumpMainLoop() returned true: it's done. Okay, done with frameTimer. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ea0b950e62..ce85415fea 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1646,6 +1646,7 @@ bool LLAppViewer::doFrame()  		}  		delete gServicePump; +		gServicePump = NULL;  		destroyMainloopTimeout(); @@ -1702,7 +1703,11 @@ bool LLAppViewer::cleanup()  	//dump scene loading monitor results  	if (LLSceneMonitor::instanceExists())  	{ -		LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); +		if (!isSecondInstance()) +		{ +			LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); +		} +		LLSceneMonitor::deleteSingleton();  	}  	// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block @@ -3467,6 +3472,12 @@ void LLAppViewer::writeSystemInfo()  	gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");      gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); +	std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList(); +	for (auto res_iter : resolutions) +	{ +		gDebugInfo["DisplayInfo"].append(res_iter); +	} +  	writeDebugInfo(); // Save out debug_info.log early, in case of crash.  } diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index d3e66289d1..0fd6009074 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -248,6 +248,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()          {              if (isAgentAvatarValid() &&                  gAgentAvatarp->isWearingAttachment(*it) && +                !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF!                  !LLAppearanceMgr::instance().isLinkedInCOF(*it))              {                  LLUUID item_id = *it; diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 9430bb3ca3..a696c99a82 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -398,6 +398,24 @@ void LLConversationLog::deleteBackupLogs()  	}  } +void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name) +{ +    conversations_vec_t::iterator conv_it = mConversations.begin(); +    for (; conv_it != mConversations.end(); ++conv_it) +    { +        if (conv_it->getSessionID() == session_id) +        { +            if (conv_it->getHistoryFileName() != expected_filename) +            { +                LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename); +                conv_it->updateHistoryFileName(expected_filename); +                conv_it->setConversationName(new_session_name); +            } +            break; +        } +    } +} +  bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)  { @@ -518,7 +536,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)  	}  	bool purge_required = false; -	char buffer[MAX_STRING]; +	static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare + +	char buffer[UTF_BUFFER];  	char conv_name_buffer[MAX_STRING];  	char part_id_buffer[MAX_STRING];  	char conv_id_buffer[MAX_STRING]; @@ -529,11 +549,14 @@ bool LLConversationLog::loadFromFile(const std::string& filename)  	// before CHUI-348 it was a flag of conversation voice state  	int prereserved_unused; -	while (!feof(fp) && fgets(buffer, MAX_STRING, fp)) +	memset(buffer, '\0', UTF_BUFFER); +	while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp))  	{ -		conv_name_buffer[0] = '\0'; -		part_id_buffer[0]	= '\0'; -		conv_id_buffer[0]	= '\0'; +        // force blank for added safety +        memset(conv_name_buffer, '\0', MAX_STRING); +        memset(part_id_buffer, '\0', MAX_STRING); +        memset(conv_id_buffer, '\0', MAX_STRING); +        memset(history_file_name, '\0', MAX_STRING);  		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",  				&time, @@ -570,6 +593,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)  		}  		mConversations.push_back(conversation); +		memset(buffer, '\0', UTF_BUFFER);  	}  	fclose(fp); diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 46e46a3278..820a5db491 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -59,7 +59,7 @@ public:  						getTime()				const	{ return mTime; }  	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; } -	void setConversationName(std::string conv_name) { mConversationName = conv_name; } +	void setConversationName(const std::string &conv_name) { mConversationName = conv_name; }  	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }  	bool isOlderThan(U32Days days) const; @@ -68,6 +68,8 @@ public:  	 */  	void updateTimestamp(); +    void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; } +  	/*  	 * Resets flag of unread offline message to false when im floater with this conversation is opened.  	 */ @@ -137,6 +139,8 @@ public:  	 * public method which is called on viewer exit to save conversation log  	 */  	void cache(); +    // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't +	void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name);  	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);  	void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);  	void deleteBackupLogs(); diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4aa74a550c..fbdf08d8aa 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -341,11 +341,28 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)  void LLConversationItemSession::clearParticipants()  { +    // clearParticipants function potentially is malfunctioning since it only cleans children of models, +    // it does nothing to views that own those models (listeners) +    // probably needs to post some kind of 'remove all participants' event  	clearChildren();  	mIsLoaded = false;  	mNeedsRefresh = true;  } + +void LLConversationItemSession::deleteParticipantModels() +{ +    // Make sure that no views exist before use and that view-owned items were removed! +    // +    // Normally we are not supposed to delete models directly, they should be +    // owned by views and this action will result in crashes, but LLParticipantList +    // creates models separately from views (it probably shouldn't) and then those +    // models wait for idle cycles to be assigned to view. +    // this code is meant to delete 'waiting' models  +    std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); +    mChildren.clear(); +} +  LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)  {  	// This is *not* a general tree parsing algorithm. It assumes that a session contains only  diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 30c7481864..e30bfbb759 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -165,6 +165,7 @@ public:  	void removeParticipant(LLConversationItemParticipant* participant);  	void removeParticipant(const LLUUID& participant_id);  	void clearParticipants(); +	void deleteParticipantModels(); // do not use while there are existing participant views  	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);  	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 093e772abe..7c9027d1b5 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -31,6 +31,7 @@  #include <boost/bind.hpp>  #include "llagentdata.h" +#include "llavataractions.h"  #include "llconversationmodel.h"  #include "llfloaterimsession.h"  #include "llfloaterimnearbychat.h" @@ -102,6 +103,57 @@ LLConversationViewSession::~LLConversationViewSession()  	mFlashTimer->unset();  } +void LLConversationViewSession::destroyView() +{ +    // Chat can create and parent models(listeners) to session's model before creating +    // coresponding views, such participant's models normally will wait for idle cycles +    // but since we are deleting session and won't be processing any more events, make +    // sure unowned models are removed as well. +    // Might be good idea to just have an LLPointer list somewhere in LLConversationItemSession + +    LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem()); + +    // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent +    // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant) +    if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1) +    { +        // Destroy existing views +        while (!mItems.empty()) +        { +            LLFolderViewItem *itemp = mItems.back(); +            mItems.pop_back(); + +            LLFolderViewModelItem* item_vmi = itemp->getViewModelItem(); +            if (item_vmi) // supposed to exist +            { +                // unparent to remove from child list +                vmi->removeChild(item_vmi); +            } +            itemp->destroyView(); +        } + +        // Not needed in scope of sessions, but just in case +        while (!mFolders.empty()) +        { +            LLFolderViewFolder *folderp = mFolders.back(); +            mFolders.pop_back(); + +            LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem(); +            if (folder_vmi) +            { +                vmi->removeChild(folder_vmi); +            } +            folderp->destroyView(); +        } + +        // Now everything that is left in model(listener) is unowned, +        // it is safe to remove +        vmi->deleteParticipantModels(); +    } + +    LLFolderViewFolder::destroyView(); +} +  void LLConversationViewSession::setFlashState(bool flash_state)  {  	if (flash_state && !mFlashStateOn) @@ -197,8 +249,8 @@ BOOL LLConversationViewSession::postBuild()  		}  		case LLConversationItem::CONV_SESSION_NEARBY:  		{ -			LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon"); -			icon->setVisible(true); +			mItemPanel->getChild<LLLayoutPanel>("session_icon_panel")->setVisible(false); +		  			mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);  			mIsInActiveVoiceChannel = true;  			if(LLVoiceClient::instanceExists()) @@ -432,8 +484,13 @@ void LLConversationViewSession::refresh()  	vmi->resetRefresh();  	if (mSessionTitle) -	{ -		mSessionTitle->setText(vmi->getDisplayName()); +	{		 +		if (!highlightFriendTitle(vmi)) +		{ +			LLStyle::Params title_style; +			title_style.color = LLUIColorTable::instance().getColor("LabelTextColor"); +			mSessionTitle->setText(vmi->getDisplayName(), title_style); +		}  	}  	// Update all speaking indicators @@ -478,6 +535,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi  	}  } +bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi) +{ +	if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1) +	{ +		LLIMModel::LLIMSession* session=  LLIMModel::instance().findIMSession(vmi->getUUID()); +		if (session && LLAvatarActions::isFriend(session->mOtherParticipantID)) +		{ +			LLStyle::Params title_style; +			title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor"); +			mSessionTitle->setText(vmi->getDisplayName(), title_style); +			return true; +		} +	} +	return false; +} +  //  // Implementation of conversations list participant (avatar) widgets  // @@ -578,7 +651,14 @@ void LLConversationViewParticipant::draw()  	}  	else  	{ -		color = mIsSelected ? sHighlightFgColor : sFgColor; +		if (LLAvatarActions::isFriend(mUUID)) +		{ +			color = LLUIColorTable::instance().getColor("ConversationFriendColor"); +		} +		else +		{ +			color = mIsSelected ? sHighlightFgColor : sFgColor; +		}  	}  	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem()); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index c5930c8a29..0932d24dfe 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -36,6 +36,7 @@  class LLTextBox;  class LLFloater;  class LLFloaterIMContainer; +class LLConversationItem;  class LLConversationViewSession;  class LLConversationViewParticipant; @@ -66,6 +67,8 @@ protected:  public:  	virtual ~LLConversationViewSession(); +	/*virtual*/ void destroyView(); +  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void draw();  	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); @@ -93,6 +96,8 @@ public:  	LLFloater* getSessionFloater();  	bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; } +	bool highlightFriendTitle(LLConversationItem* vmi); +  private:  	void onCurrentVoiceSessionChanged(const LLUUID& session_id); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 687b13d2c8..55b3864b6d 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -2129,7 +2129,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)              if (mat)              {                 -                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) +                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaModeRender()))                  {                      case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:                      { @@ -2267,7 +2267,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);  				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); -				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  				{                      F32 cutoff = mat->getAlphaMaskCutoff()/255.f;  					sVertexProgram->setMinimumAlpha(cutoff); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4a802ad9aa..01d8b6775b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1165,7 +1165,7 @@ bool LLFace::canRenderAsMask()  	}  	LLMaterial* mat = te->getMaterialParams(); -	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) +	if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)  	{  		return false;  	} @@ -1412,7 +1412,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  			else  			{ -				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				if (!mat || mat->getDiffuseAlphaModeRender() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  				{  					shiny_in_alpha = true;  				} diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 347997a69a..7a887a2549 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -384,6 +384,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)  	mUpdateDropDownItems(true),  	mRestoreOverflowMenu(false),  	mGetPrevItems(true), +	mMouseX(0), +	mMouseY(0),  	mItemsChangedTimer()  {  	// Register callback for menus with current registrar (will be parent panel's registrar) @@ -399,7 +401,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)  	//make chevron button                                                                                                                                 	LLTextBox::Params more_button_params(p.more_button);  	mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params); -	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); +	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));  	addChild(mMoreTextBox);  	mDropDownItemsCount = 0; @@ -975,6 +977,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it  	return TRUE;  } +void LLFavoritesBarCtrl::onMoreTextBoxClicked() +{ +	LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY); +	showDropDownMenu(); +} +  void LLFavoritesBarCtrl::showDropDownMenu()  {  	if (mOverflowMenuHandle.isDead()) @@ -1130,7 +1138,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)  		}  	} -	LLMenuGL::showPopup(this, menu, menu_x, menu_y); +	LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY);  }  void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 571208aa31..868f1c83c8 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -96,6 +96,8 @@ protected:  	void showDropDownMenu(); +	void onMoreTextBoxClicked(); +  	LLHandle<LLView> mOverflowMenuHandle;  	LLHandle<LLView> mContextMenuHandle; @@ -163,6 +165,9 @@ private:  	BOOL mTabsHighlightEnabled; +	S32 mMouseX; +	S32 mMouseY; +  	boost::signals2::connection mEndDragConnection;  }; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index d915a9fd26..dc9816c9f7 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -379,22 +379,6 @@ F32 gpu_benchmark();  #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ -    if (code == STATUS_MSC_EXCEPTION) -    { -        // C++ exception, go on -        return EXCEPTION_CONTINUE_SEARCH; -    } -    else -    { -        // handle it -        return EXCEPTION_EXECUTE_HANDLER; -    } -} -  F32 logExceptionBenchmark()  {      // Todo: make a wrapper/class for SEH exceptions @@ -403,7 +387,7 @@ F32 logExceptionBenchmark()      {          gbps = gpu_benchmark();      } -    __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation())) +    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))      {          // convert to C++ styled exception          char integer_string[32]; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 4d3ebcda1e..ea93d3bfaa 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -49,7 +49,8 @@  #include "lltrans.h"  LLFloaterBuy::LLFloaterBuy(const LLSD& key) -:	LLFloater(key) +:	LLFloater(key), +	mSelectionUpdateSlot()  {  } @@ -179,12 +180,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)  	floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));  	floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name); +	floater->showViews(true); +  	// Must do this after the floater is created, because  	// sometimes the inventory is already there and   	// the callback is called immediately.  	LLViewerObject* obj = selection->getFirstRootObject();  	floater->registerVOInventoryListener(obj,NULL);  	floater->requestVOInventory(); + +	if (!floater->mSelectionUpdateSlot.connected()) +	{ +		floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater)); +	}  }  void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, @@ -280,6 +288,30 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,  	removeVOInventoryListener();  } +void LLFloaterBuy::onSelectionChanged() +{ +	 +	if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0) +	{ +		removeVOInventoryListener(); +		closeFloater(); +	} +	else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1) +	{ +		removeVOInventoryListener(); +		showViews(false); +		reset(); +		setTitle(getString("mupliple_selected")); +	} +} + +void LLFloaterBuy::showViews(bool show) +{ +	getChild<LLUICtrl>("buy_btn")->setEnabled(show); +	getChild<LLUICtrl>("buy_text")->setVisible(show); +	getChild<LLUICtrl>("buy_name_text")->setVisible(show); +} +  void LLFloaterBuy::onClickBuy()  {  	// Put the items where we put new folders. @@ -303,5 +335,10 @@ void LLFloaterBuy::onClickCancel()  // virtual  void LLFloaterBuy::onClose(bool app_quitting)  { +	if (mSelectionUpdateSlot.connected()) +	{ +		mSelectionUpdateSlot.disconnect(); +	} +  	mObjectSelection.clear();  } diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h index 3ec642dee1..e83b3c6ba6 100644 --- a/indra/newview/llfloaterbuy.h +++ b/indra/newview/llfloaterbuy.h @@ -63,12 +63,17 @@ protected:  								 S32 serial_num,  								 void* data); +	void onSelectionChanged(); +	void showViews(bool show); +  	void onClickBuy();  	void onClickCancel();  private:  	LLSafeHandle<LLObjectSelection>	mObjectSelection;  	LLSaleInfo mSaleInfo; + +	boost::signals2::connection mSelectionUpdateSlot;  };  #endif diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index d574f1433f..3b192ff81b 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -457,6 +457,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)  	switch (mode)  	{ +	case CAMERA_CTRL_MODE_PRESETS:  	case CAMERA_CTRL_MODE_PAN:  		sFreeCamera = false;  		clear_camera_tool(); @@ -467,13 +468,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)  		activate_camera_tool();  		break; -	case CAMERA_CTRL_MODE_PRESETS: -		if(sFreeCamera) -		{ -			switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); -		} -		break; -  	default:  		//normally we won't occur here  		llassert_always(FALSE); @@ -528,7 +522,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param)  		{  			camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);  			camera_floater->updateItemsSelection(); -			camera_floater->fromFreeToPresets();  		}  	}  	else @@ -586,15 +579,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name)  	if (camera_floater)  	{  		camera_floater->updateItemsSelection(); -		camera_floater->fromFreeToPresets(); -	} -} - -void LLFloaterCamera::fromFreeToPresets() -{ -	if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS) -	{ -		switchMode(CAMERA_CTRL_MODE_PRESETS); +		camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS);  	}  } diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 9440f50c3f..a69b87ad16 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -69,10 +69,6 @@ public:  	/*switch to one of the camera presets (front, rear, side)*/  	static void switchToPreset(const std::string& name); -	/* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and -	   are not in free camera mode*/ -	void fromFreeToPresets(); -  	virtual void onOpen(const LLSD& key);  	virtual void onClose(bool app_quitting); diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp new file mode 100644 index 0000000000..e888144b6a --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -0,0 +1,479 @@ +/**  + * @file llfloatereditenvironmentbase.cpp + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatereditenvironmentbase.h" + +#include <boost/make_shared.hpp> + +// libs +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llfilepicker.h" +#include "llsettingspicker.h" +#include "llviewerparcelmgr.h" + +// newview +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llenvironment.h" +#include "llagent.h" +#include "llparcel.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" + +namespace +{ +    const std::string ACTION_APPLY_LOCAL("apply_local"); +    const std::string ACTION_APPLY_PARCEL("apply_parcel"); +    const std::string ACTION_APPLY_REGION("apply_region"); +} + +//========================================================================= +const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id"); + + +//========================================================================= + +class LLFixedSettingCopiedCallback : public LLInventoryCallback +{ +public: +    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {} + +    virtual void fire(const LLUUID& inv_item_id) +    { +        if (!mHandle.isDead()) +        { +            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); +            if (item) +            { +                LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get(); +                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); +            } +        } +    } + +private: +    LLHandle<LLFloater> mHandle; +}; + +//========================================================================= +LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) : +    LLFloater(key), +    mInventoryId(), +    mInventoryItem(nullptr), +    mIsDirty(false), +    mCanCopy(false), +    mCanMod(false), +    mCanTrans(false), +    mCanSave(false) +{ +} + +LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase() +{ +} + +void LLFloaterEditEnvironmentBase::onFocusReceived() +{ +    if (isInVisibleChain()) +    { +        updateEditEnvironment(); +        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); +    } +} + +void LLFloaterEditEnvironmentBase::onFocusLost() +{ +} + +void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans) +{ +    if (inventoryId.isNull()) +    { +        mInventoryItem = nullptr; +        mInventoryId.setNull(); +        mCanMod = true; +        mCanCopy = true; +        mCanTrans = true; +        return; +    } + +    mInventoryId = inventoryId; +    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; +    mInventoryItem = gInventory.getItem(mInventoryId); + +    if (!mInventoryItem) +    { +        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; +        LLNotificationsUtil::add("CantFindInvItem"); +        closeFloater(); + +        mInventoryId.setNull(); +        mInventoryItem = nullptr; +        return; +    } + +    if (mInventoryItem->getAssetUUID().isNull()) +    { +        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; +        LLNotificationsUtil::add("UnableEditItem"); +        closeFloater(); + +        mInventoryId.setNull(); +        mInventoryItem = nullptr; +        return; +    } + +    mCanSave = true; +    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); +    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); +    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + +    mExpectingAssetId = mInventoryItem->getAssetUUID(); +    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), +        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); +} + + +void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb) +{ +    if (isDirty()) +    { +        LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType()) +            ("NAME", getEditSettings()->getName())); + +        // create and show confirmation textbox +        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), +            [cb](const LLSD¬if, const LLSD&resp) +            { +                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); +                if (opt == 0) +                    cb(); +            }); +    } +    else if (cb) +    { +        cb(); +    } +} + +void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ +    if (asset_id != mExpectingAssetId) +    { +        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; +        return; +    } +    mExpectingAssetId.setNull(); +    clearDirtyFlag(); + +    if (!settings || status) +    { +        LLSD args; +        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); +        LLNotificationsUtil::add("FailedToFindSettings", args); +        closeFloater(); +        return; +    } + +    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) +    { +        mCanSave = false; +        mCanCopy = false; +        mCanMod = false; +        mCanTrans = false; +    } +    else +    { +        if (mInventoryItem) +            settings->setName(mInventoryItem->getName()); + +        if (mCanCopy) +            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); +        else +            settings->setFlag(LLSettingsBase::FLAG_NOCOPY); + +        if (mCanMod) +            settings->clearFlag(LLSettingsBase::FLAG_NOMOD); +        else +            settings->setFlag(LLSettingsBase::FLAG_NOMOD); + +        if (mCanTrans) +            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); +        else +            settings->setFlag(LLSettingsBase::FLAG_NOTRANS); +    } + +    setEditSettingsAndUpdate(settings); +} + +void LLFloaterEditEnvironmentBase::onButtonImport() +{ +    checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); }); +} + +void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (0 == option) +    { +        std::string settings_name = response["message"].asString(); + +        LLInventoryObject::correctInventoryName(settings_name); +        if (settings_name.empty()) +        { +            // Ideally notification should disable 'OK' button if name won't fit our requirements, +            // for now either display notification, or use some default name +            settings_name = "Unnamed"; +        } + +        if (mCanMod) +        { +            doApplyCreateNewInventory(settings_name, settings); +        } +        else if (mInventoryItem) +        { +            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); +            LLUUID parent_id = mInventoryItem->getParentUUID(); +            if (marketplacelistings_id == parent_id) +            { +                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); +            } + +            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle()); +            copy_inventory_item( +                gAgent.getID(), +                mInventoryItem->getPermissions().getOwner(), +                mInventoryItem->getUUID(), +                parent_id, +                settings_name, +                cb); +        } +        else +        { +            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; +        } +    } +} + +void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting) +{ +    if (!app_quitting) +        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); +    else +        closeFloater(); +} + +void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) +{ +    if (mInventoryItem) +    { +        LLUUID parent_id = mInventoryItem->getParentUUID(); +        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); +        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    } +    else +    { +        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); +        // This method knows what sort of settings object to create. +        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    } +} + +void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) +{ +    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; +    if (mInventoryId.isNull()) +    { +        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    } +    else +    { +        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); +    } +} + +void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) +{ +    U32 flags(0); + +    if (mInventoryItem) +    { +        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) +            flags |= LLSettingsBase::FLAG_NOMOD; +        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) +            flags |= LLSettingsBase::FLAG_NOTRANS; +    } + +    flags |= settings->getFlags(); +    settings->setFlag(flags); + +    if (where == ACTION_APPLY_LOCAL) +    { +        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. +        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); +    } +    else if (where == ACTION_APPLY_PARCEL) +    { +        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); + +        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) +        { +            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; +            LLNotificationsUtil::add("WLParcelApplyFail"); +            return; +        } + +        if (mInventoryItem && !isDirty()) +        { +            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); +        } +        else if (settings->getSettingsType() == "sky") +        { +            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); +        } +        else if (settings->getSettingsType() == "water") +        { +            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); +        } +        else if (settings->getSettingsType() == "day") +        { +            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsDay>(settings), -1, -1); +        } +    } +    else if (where == ACTION_APPLY_REGION) +    { +        if (mInventoryItem && !isDirty()) +        { +            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); +        } +        else if (settings->getSettingsType() == "sky") +        { +            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); +        } +        else if (settings->getSettingsType() == "water") +        { +            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); +        } +        else if (settings->getSettingsType() == "day") +        { +            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsDay>(settings), -1, -1); +        } +    } +    else +    { +        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; +        return; +    } + +} + +void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting) +{ +    LLFloater* floaterp = mInventoryFloater.get(); + +    if (floaterp) +    { +        floaterp->closeFloater(quitting); +    } +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ +    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + +    if (inventory_id.isNull() || !results["success"].asBoolean()) +    { +        LLNotificationsUtil::add("CantCreateInventory"); +        return; +    } +    onInventoryCreated(asset_id, inventory_id); +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) +{ +    bool can_trans = true; +    if (mInventoryItem) +    { +        LLPermissions perms = mInventoryItem->getPermissions(); + +        LLInventoryItem *created_item = gInventory.getItem(mInventoryId); + +        if (created_item) +        { +            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); +            created_item->setPermissions(perms); +            created_item->updateServer(false); +        } +    } + +    clearDirtyFlag(); +    setFocus(TRUE);                 // Call back the focus... +    loadInventoryItem(inventory_id, can_trans); +} + +void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ +    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + +    clearDirtyFlag(); +    if (inventory_id != mInventoryId) +    { +        loadInventoryItem(inventory_id); +    } +} + +void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value) +{ +    if (value) +        setDirtyFlag(); +} + +//------------------------------------------------------------------------- +bool LLFloaterEditEnvironmentBase::canUseInventory() const +{ +    return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterEditEnvironmentBase::canApplyRegion() const +{ +    return gAgent.canManageEstate(); +} + +bool LLFloaterEditEnvironmentBase::canApplyParcel() const +{ +    return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); +} + +//========================================================================= diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h new file mode 100644 index 0000000000..7c7cf5bdcd --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.h @@ -0,0 +1,148 @@ +/**  + * @file llfloatereditenvironmentbase.h + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATEREDITENVIRONMENTBASE_H +#define LL_FLOATEREDITENVIRONMENTBASE_H + +#include "llfloater.h" +#include "llsettingsbase.h" +#include "llflyoutcombobtn.h" +#include "llinventory.h" + +#include "boost/signals2.hpp" + +class LLTabContainer; +class LLButton; +class LLLineEditor; +class LLFloaterSettingsPicker; +class LLFixedSettingCopiedCallback; + +class LLFloaterEditEnvironmentBase : public LLFloater +{ +    LOG_CLASS(LLFloaterEditEnvironmentBase); + +    friend class LLFixedSettingCopiedCallback; + +public: +    static const std::string    KEY_INVENTORY_ID; + +                            LLFloaterEditEnvironmentBase(const LLSD &key); +                            ~LLFloaterEditEnvironmentBase(); + +    virtual void            onFocusReceived()           override; +    virtual void            onFocusLost()               override; +     +    virtual LLSettingsBase::ptr_t   getEditSettings()   const = 0; + +    virtual BOOL            isDirty() const override            { return getIsDirty(); } + +protected: +    typedef std::function<void()> on_confirm_fn; + +    virtual void            setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0; +    virtual void            updateEditEnvironment() = 0; + +    virtual LLFloaterSettingsPicker *getSettingsPicker() = 0; + +    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true); + +    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb); + +    virtual void            doImportFromDisk() = 0; +    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); +    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); +    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); +    void                    doCloseInventoryFloater(bool quitting = false); + +    bool                    canUseInventory() const; +    bool                    canApplyRegion() const; +    bool                    canApplyParcel() const; + +    LLUUID                  mInventoryId; +    LLInventoryItem *       mInventoryItem; +    LLHandle<LLFloater>     mInventoryFloater; +    bool                    mCanCopy; +    bool                    mCanMod; +    bool                    mCanTrans; +    bool                    mCanSave; + +    bool                    mIsDirty; + +    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); +    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); +    void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + +    bool                    getIsDirty() const  { return mIsDirty; } +    void                    setDirtyFlag()      { mIsDirty = true; } +    virtual void            clearDirtyFlag() = 0; + +    void                    onPanelDirtyFlagChanged(bool); + +    virtual void            onClickCloseBtn(bool app_quitting = false) override; +    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); +    void                    onButtonImport(); + +    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); + +private: +    LLUUID                  mExpectingAssetId; // for asset load confirmation +}; + +class LLSettingsEditPanel : public LLPanel +{ +public: +    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; + +    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg; +    typedef boost::signals2::connection connection_t; + +    inline bool         getIsDirty() const      { return mIsDirty; } +    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } +    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } + +    inline bool        getCanChangeSettings() const    { return mCanEdit; } +    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; } + +    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); } + + +protected: +    LLSettingsEditPanel() : +        LLPanel(), +        mIsDirty(false), +        mOnDirtyChanged() +    {} + +private: +    void onTextureChanged(LLUUID &inventory_item_id); + +    bool                mIsDirty; +    bool                mCanEdit; +     +    on_dirty_charged_sg mOnDirtyChanged; +}; + +#endif // LL_FLOATERENVIRONMENTBASE_H diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index a7c2cbbeaa..0501c287ad 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -125,7 +125,6 @@ namespace {  }  //========================================================================= -const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id");  const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");  const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");  const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod"); @@ -133,7 +132,7 @@ const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");  const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");  const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");  const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region"); - +/*  //=========================================================================  class LLDaySettingCopiedCallback : public LLInventoryCallback @@ -156,12 +155,12 @@ public:  private:      LLHandle<LLFloater> mHandle; -}; +};*/  //=========================================================================  LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : -    LLFloater(key), +    LLFloaterEditEnvironmentBase(key),      mFlyoutControl(nullptr),      mDayLength(0),      mCurrentTrack(1), @@ -170,19 +169,12 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :      mFramesSlider(nullptr),      mCurrentTimeLabel(nullptr),      mImportButton(nullptr), -    mInventoryId(), -    mInventoryItem(nullptr),      mLoadFrame(nullptr),      mSkyBlender(),      mWaterBlender(),      mScratchSky(),      mScratchWater(),      mIsPlaying(false), -    mIsDirty(false), -    mCanSave(false), -    mCanCopy(false), -    mCanMod(false), -    mCanTrans(false),      mCloneTrack(nullptr),      mLoadTrack(nullptr),      mClearTrack(nullptr) @@ -425,19 +417,6 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting)      }  } -void LLFloaterEditExtDayCycle::onFocusReceived() -{ -    if (isInVisibleChain()) -    { -        updateEditEnvironment(); -        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); -    } -} - -void LLFloaterEditExtDayCycle::onFocusLost() -{ -} -  void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)  { @@ -488,6 +467,10 @@ void LLFloaterEditExtDayCycle::refresh()      LLFloater::refresh();  } +void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ +    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings)); +}  void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)  { @@ -700,63 +683,6 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)      }  } -void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day) -{ -    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -    if (0 == option) -    { -        std::string settings_name = response["message"].asString(); - -        LLInventoryObject::correctInventoryName(settings_name); -        if (settings_name.empty()) -        { -            // Ideally notification should disable 'OK' button if name won't fit our requirements, -            // for now either display notification, or use some default name -            settings_name = "Unnamed"; -        } - -        if (mCanMod) -        { -            doApplyCreateNewInventory(day, settings_name); -        } -        else if (mInventoryItem) -        { -            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); -            LLUUID parent_id = mInventoryItem->getParentUUID(); -            if (marketplacelistings_id == parent_id) -            { -                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); -            } - -            LLPointer<LLInventoryCallback> cb = new LLDaySettingCopiedCallback(getHandle()); -            copy_inventory_item( -                gAgent.getID(), -                mInventoryItem->getPermissions().getOwner(), -                mInventoryItem->getUUID(), -                parent_id, -                settings_name, -                cb); -        } -        else -        { -            LL_WARNS() << "Failed to copy day setting" << LL_ENDL; -        } -    } -} - -void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/) -{ -    if (!app_quitting) -        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); -    else -        closeFloater(); -} - -void LLFloaterEditExtDayCycle::onButtonImport() -{ -    checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); }); -} -  void LLFloaterEditExtDayCycle::onButtonLoadFrame()  {      doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null); @@ -1053,35 +979,6 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)      selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);  } - -void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value) -{ -    if (value) -        setDirtyFlag(); -} - -void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb) -{ -    if (isDirty()) -    { -        LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType()) -            ("NAME", mEditDay->getName())); - -        // create and show confirmation textbox -        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), -            [cb](const LLSD¬if, const LLSD&resp) -            { -                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); -                if (opt == 0) -                    cb(); -            }); -    } -    else if (cb) -    { -        cb(); -    } -} -  void LLFloaterEditExtDayCycle::onTimeSliderCallback()  {      stopPlay(); @@ -1435,106 +1332,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi      return mCommitSignal.connect(cb);  } -void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans) -{ -    if (inventoryId.isNull()) -    { -        mInventoryItem = nullptr; -        mInventoryId.setNull(); -        mCanSave = true; -        mCanCopy = true; -        mCanMod = true; -        mCanTrans = true; -        return; -    } - -    mInventoryId = inventoryId; -    LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; -    mInventoryItem = gInventory.getItem(mInventoryId); - -    if (!mInventoryItem) -    { -        LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; - -        LLNotificationsUtil::add("CantFindInvItem"); -        closeFloater(); -        mInventoryId.setNull(); -        mInventoryItem = nullptr; -        return; -    } - -    if (mInventoryItem->getAssetUUID().isNull()) -    { -        LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" <<  LL_ENDL; - -        LLNotificationsUtil::add("UnableEditItem"); -        closeFloater(); - -        mInventoryId.setNull(); -        mInventoryItem = nullptr; -        return; -    } - -    mCanSave = true; -    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); -    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); -    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - -    mExpectingAssetId = mInventoryItem->getAssetUUID(); -    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), -        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ -    if (asset_id != mExpectingAssetId) -    { -        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; -        return; -    } -    mExpectingAssetId.setNull(); -    clearDirtyFlag(); - -    if (!settings || status) -    { -        LLSD args; -        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); -        LLNotificationsUtil::add("FailedToFindSettings", args); -        closeFloater(); -        return; -    } - -    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) -    { -        mCanSave = false; -        mCanCopy = false; -        mCanMod = false; -        mCanTrans = false; -    } -    else -    { -        if (mCanCopy) -            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); -        else -            settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - -        if (mCanMod) -            settings->clearFlag(LLSettingsBase::FLAG_NOMOD); -        else -            settings->setFlag(LLSettingsBase::FLAG_NOMOD); - -        if (mCanTrans) -            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); -        else -            settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - -        if (mInventoryItem) -            settings->setName(mInventoryItem->getName()); -    } - -    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings)); -} -  void LLFloaterEditExtDayCycle::updateEditEnvironment(void)  {      if (!mEditDay) @@ -1670,93 +1467,6 @@ void LLFloaterEditExtDayCycle::reblendSettings()      mWaterBlender->setPosition(position);      } -void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name) -{ -    if (mInventoryItem) -    { -        LLUUID parent_id = mInventoryItem->getParentUUID(); -        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); -        LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name, -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    } -    else -    { -        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); -        // This method knows what sort of settings object to create. -        LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name, -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    } -} - -void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day) -{ -    if (mInventoryId.isNull()) -        LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), -                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    else -        LLSettingsVOBase::updateInventoryItem(day, mInventoryId, -                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); -} - -void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day) -{ -    U32 flags(0); - -    if (mInventoryItem) -    { -        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) -            flags |= LLSettingsBase::FLAG_NOMOD; -        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) -            flags |= LLSettingsBase::FLAG_NOTRANS; -    } - -    flags |= day->getFlags(); -    day->setFlag(flags); - -    if (where == ACTION_APPLY_LOCAL) -    { -        day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. -        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day); -    } -    else if (where == ACTION_APPLY_PARCEL) -    { -        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - -        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) -        { -            LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL; -            LLNotificationsUtil::add("WLParcelApplyFail"); -            return; -        } - -        if (mInventoryItem && !isDirty()) -        { -            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); -        } -        else -        { -            LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1); -        } -    } -    else if (where == ACTION_APPLY_REGION) -    { -        if (mInventoryItem && !isDirty()) -        { -            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); -        } -        else -        { -            LLEnvironment::instance().updateRegion(day, -1, -1); -        } -    } -    else -    { -        LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL; -        return; -    } - -} -  void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)  {      if (!mCommitSignal.empty()) @@ -1793,51 +1503,6 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()      return mFramesSlider->canAddSliders();  } -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ -    LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; - -    if (inventory_id.isNull() || !results["success"].asBoolean()) -    { -        LLNotificationsUtil::add("CantCreateInventory"); -        return; -    } -    onInventoryCreated(asset_id, inventory_id); -} - -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) -{ -    bool can_trans = true; -    if (mInventoryItem) -    { -        LLPermissions perms = mInventoryItem->getPermissions(); - -        LLInventoryItem *created_item = gInventory.getItem(mInventoryId); -         -        if (created_item) -        { -            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); -            created_item->setPermissions(perms); -            created_item->updateServer(false); -        } -    } - -    clearDirtyFlag(); -    setFocus(TRUE);                 // Call back the focus... -    loadInventoryItem(inventory_id, can_trans); -} - -void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ -    LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; - -    clearDirtyFlag(); -    if (inventory_id != mInventoryId) -    { -        loadInventoryItem(inventory_id); -    } -} -  void LLFloaterEditExtDayCycle::doImportFromDisk()  {   // Load a a legacy Windlight XML from disk.      (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile(); @@ -1864,21 +1529,6 @@ void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string      setEditDayCycle(legacyday);  } -bool LLFloaterEditExtDayCycle::canUseInventory() const -{ -    return LLEnvironment::instance().isInventoryEnabled(); -} - -bool LLFloaterEditExtDayCycle::canApplyRegion() const -{ -    return gAgent.canManageEstate(); -} - -bool LLFloaterEditExtDayCycle::canApplyParcel() const -{ -    return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); -} -  void LLFloaterEditExtDayCycle::startPlay()  {      doCloseInventoryFloater(); @@ -1983,14 +1633,8 @@ void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)      }  } -void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id) +LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()  { -    cloneTrack(track_id, mCurrentTrack); -} - -void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem) -{ -//  LLUI::sWindow->setCursor(UI_CURSOR_WAIT);      LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());      // Show the dialog @@ -2003,7 +1647,17 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ          picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });      } +    return picker; +} + +void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id) +{ +    cloneTrack(track_id, mCurrentTrack); +} +void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem) +{ +    LLFloaterSettingsPicker *picker = getSettingsPicker();      picker->setSettingsFilter(type);      picker->setSettingsItemId(curritem);      if (type == LLSettingsType::ST_DAYCYCLE) @@ -2018,16 +1672,6 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ      picker->setFocus(TRUE);  } -void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting) -{ -    LLFloater* floaterp = mInventoryFloater.get(); - -    if (floaterp) -    { -        floaterp->closeFloater(quitting); -    } -} -  void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)  {      LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue()); @@ -2118,7 +1762,9 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID      LLInventoryItem *inv_item = gInventory.getItem(item_id); -    if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) +    if (inv_item +        && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) +            || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))      {          // Need to check if item is already no-transfer, otherwise make it no-transfer          bool no_transfer = false; diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index b6e9fdb14f..9a30fb199f 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -32,6 +32,7 @@  #include <boost/signals2.hpp>  #include "llenvironment.h" +#include "llfloatereditenvironmentbase.h"  class LLCheckBoxCtrl;  class LLComboBox; @@ -50,14 +51,13 @@ typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;  /**   * Floater for creating or editing a day cycle.   */ -class LLFloaterEditExtDayCycle : public LLFloater +class LLFloaterEditExtDayCycle : public LLFloaterEditEnvironmentBase  {  	LOG_CLASS(LLFloaterEditExtDayCycle);      friend class LLDaySettingCopiedCallback;  public: -    static const std::string    KEY_INVENTORY_ID;      static const std::string    KEY_EDIT_CONTEXT;      static const std::string    KEY_DAY_LENGTH;      static const std::string    KEY_CANMOD; @@ -82,8 +82,8 @@ public:      virtual BOOL                postBuild() override;      virtual void                onOpen(const LLSD& key) override;      virtual void                onClose(bool app_quitting) override; -    virtual void                onFocusReceived() override; -    virtual void                onFocusLost() override; +    //virtual void                onFocusReceived() override; +    //virtual void                onFocusLost() override;      virtual void                onVisibilityChange(BOOL new_visibility) override;      connection_t                setEditCommitSignal(edit_commit_signal_t::slot_type cb); @@ -97,10 +97,13 @@ public:      LLUUID                      getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; }      LLUUID                      getEditingInventoryId() { return mInventoryId; } +    virtual LLSettingsBase::ptr_t getEditSettings()   const override { return mEditDay; } +      BOOL			            handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override; -    BOOL                        isDirty() const override { return getIsDirty(); }  +protected: +    virtual void                setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;  private:      typedef std::function<void()> on_confirm_fn; @@ -108,8 +111,8 @@ private:  	// flyout response/click  	void                        onButtonApply(LLUICtrl *ctrl, const LLSD &data); -    virtual void                onClickCloseBtn(bool app_quitting = false) override; -    void                        onButtonImport(); +    //virtual void                onClickCloseBtn(bool app_quitting = false) override; +    //void                        onButtonImport();      void                        onButtonLoadFrame();      void                        onAddFrame();  	void                        onRemoveFrame(); @@ -119,7 +122,6 @@ private:  	void                        onCommitName(class LLLineEditor* caller, void* user_data);  	void                        onTrackSelectionCallback(const LLSD& user_data);  	void                        onPlayActionCallback(const LLSD& user_data); -	void                        onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day);  	// time slider clicked  	void                        onTimeSliderCallback();  	// a frame moved or frame selection changed @@ -128,10 +130,6 @@ private:      void                        onFrameSliderMouseDown(S32 x, S32 y, MASK mask);      void                        onFrameSliderMouseUp(S32 x, S32 y, MASK mask); -    void                        onPanelDirtyFlagChanged(bool); - -    void                        checkAndConfirmSettingsLoss(on_confirm_fn cb); -      void                        cloneTrack(U32 source_index, U32 dest_index);      void                        cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index);  	void                        selectTrack(U32 track_index, bool force = false); @@ -148,25 +146,21 @@ private:      void                        removeCurrentSliderFrame();      void                        removeSliderFrame(F32 frame); -    void                        loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true); -    void                        onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status); - -    void                        doImportFromDisk(); +    virtual void                doImportFromDisk() override;      void                        loadSettingFromFile(const std::vector<std::string>& filenames); -    void                        doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name); -    void                        doApplyUpdateInventory(const LLSettingsDay::ptr_t &day); -    void                        doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);      void                        doApplyCommit(LLSettingsDay::ptr_t day);      void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);      void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);      void                        onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); +      void                        doOpenTrackFloater(const LLSD &args);      void                        doCloseTrackFloater(bool quitting = false); +    virtual LLFloaterSettingsPicker* getSettingsPicker() override;      void                        onPickerCommitTrackId(U32 track_id);      void                        doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem); -    void                        doCloseInventoryFloater(bool quitting = false); +    //void                        doCloseInventoryFloater(bool quitting = false);      void                        onPickerCommitSetting(LLUUID item_id, S32 track);      void                        onAssetLoadedForInsertion(LLUUID item_id,                                                            LLUUID asset_id, @@ -176,11 +170,7 @@ private:                                                            S32 dest_track,                                                            LLSettingsBase::TrackPosition dest_frame); -    bool                        canUseInventory() const; -    bool                        canApplyRegion() const; -    bool                        canApplyParcel() const; - -    void                        updateEditEnvironment(); +    virtual void                updateEditEnvironment() override;      void                        synchronizeTabs();      void                        reblendSettings(); @@ -193,7 +183,7 @@ private:      bool                        getIsDirty() const  { return mIsDirty; }      void                        setDirtyFlag()      { mIsDirty = true; } -    virtual void                clearDirtyFlag(); +    virtual void                clearDirtyFlag() override;      bool                        isRemovingFrameAllowed();      bool                        isAddingFrameAllowed(); @@ -218,11 +208,8 @@ private:      LLView*                     mSkyTabLayoutContainer;      LLView*                     mWaterTabLayoutContainer;      LLTextBox*                  mCurrentTimeLabel; -    LLUUID                      mInventoryId; -    LLInventoryItem *           mInventoryItem;      LLFlyoutComboBtnCtrl *      mFlyoutControl; -    LLHandle<LLFloater>         mInventoryFloater;      LLHandle<LLFloater>         mTrackFloater;      LLTrackBlenderLoopingManual::ptr_t  mSkyBlender; @@ -236,11 +223,6 @@ private:      LLFrameTimer                mPlayTimer;      F32                         mPlayStartFrame; // an env frame      bool                        mIsPlaying; -    bool                        mIsDirty; -    bool                        mCanCopy; -    bool                        mCanMod; -    bool                        mCanTrans; -    bool                        mCanSave;      edit_commit_signal_t        mCommitSignal; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index cd8e0a48e7..41bbd5e8f9 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -81,44 +81,11 @@ namespace      const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");  } -//========================================================================= -const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id"); - - -//========================================================================= - -class LLFixedSettingCopiedCallback : public LLInventoryCallback -{ -public: -    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {} - -    virtual void fire(const LLUUID& inv_item_id) -    { -        if (!mHandle.isDead()) -        { -            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); -            if (item) -            { -                LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get(); -                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); -            } -        } -    } - -private: -    LLHandle<LLFloater> mHandle; -};  //=========================================================================  LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) : -    LLFloater(key), -    mFlyoutControl(nullptr), -    mInventoryId(), -    mInventoryItem(nullptr), -    mIsDirty(false), -    mCanCopy(false), -    mCanMod(false), -    mCanTrans(false) +    LLFloaterEditEnvironmentBase(key), +    mFlyoutControl(nullptr)  {  } @@ -176,19 +143,6 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting)      syncronizeTabs();  } -void LLFloaterFixedEnvironment::onFocusReceived() -{ -    if (isInVisibleChain()) -    { -        updateEditEnvironment(); -        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); -    } -} - -void LLFloaterFixedEnvironment::onFocusLost() -{ -} -  void LLFloaterFixedEnvironment::refresh()  {      if (!mSettings) @@ -220,6 +174,15 @@ void LLFloaterFixedEnvironment::refresh()      }  } +void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ +    mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ? +    updateEditEnvironment(); +    syncronizeTabs(); +    refresh(); +    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); +} +  void LLFloaterFixedEnvironment::syncronizeTabs()  {      S32 count = mTab->getTabCount(); @@ -250,131 +213,9 @@ LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker()      return picker;  } -void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans) -{ -    if (inventoryId.isNull()) -    { -        mInventoryItem = nullptr; -        mInventoryId.setNull(); -        mCanMod = true; -        mCanCopy = true; -        mCanTrans = true; -        return; -    } - -    mInventoryId = inventoryId; -    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; -    mInventoryItem = gInventory.getItem(mInventoryId); - -    if (!mInventoryItem) -    { -        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; -        LLNotificationsUtil::add("CantFindInvItem"); -        closeFloater(); - -        mInventoryId.setNull(); -        mInventoryItem = nullptr; -        return; -    } - -    if (mInventoryItem->getAssetUUID().isNull()) -    { -        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; -        LLNotificationsUtil::add("UnableEditItem"); -        closeFloater(); - -        mInventoryId.setNull(); -        mInventoryItem = nullptr; -        return; -    } - -    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); -    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); -    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - -    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), -        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - - -void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb) -{ -    if (isDirty()) -    { -        LLSD args(LLSDMap("TYPE", mSettings->getSettingsType()) -            ("NAME", mSettings->getName())); - -        // create and show confirmation textbox -        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), -            [cb](const LLSD¬if, const LLSD&resp) -            { -                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); -                if (opt == 0) -                    cb(); -            }); -    } -    else if (cb) -    { -        cb(); -    } -} -  void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id)  {      loadInventoryItem(item_id); -//     mInventoryId = item_id; -//     mInventoryItem = gInventory.getItem(mInventoryId); -//  -//     mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); -//     mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); -//     mCanTrans = mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); -//  -//     LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), -//         [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ -    if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id) -    { -        LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL; -        return; -    } - -    clearDirtyFlag(); - -    if (!settings || status) -    { -        LLSD args; -        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); -        LLNotificationsUtil::add("FailedToFindSettings", args); -        closeFloater(); -        return; -    } - -    mSettings = settings; -    if (mInventoryItem) -        mSettings->setName(mInventoryItem->getName()); - -    if (mCanCopy) -        settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); -    else -        settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - -    if (mCanMod) -        settings->clearFlag(LLSettingsBase::FLAG_NOMOD); -    else -        settings->setFlag(LLSettingsBase::FLAG_NOMOD); - -    if (mCanTrans) -        settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); -    else -        settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - -    updateEditEnvironment(); -    syncronizeTabs(); -    refresh(); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST);  }  void LLFloaterFixedEnvironment::onNameChanged(const std::string &name) @@ -473,50 +314,6 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)      }  } -void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) -{ -    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -    if (0 == option) -    { -        std::string settings_name = response["message"].asString(); - -        LLInventoryObject::correctInventoryName(settings_name); -        if (settings_name.empty()) -        { -            // Ideally notification should disable 'OK' button if name won't fit our requirements, -            // for now either display notification, or use some default name -            settings_name = "Unnamed"; -        } - -        if (mCanMod) -        { -            doApplyCreateNewInventory(settings_name, settings); -        } -        else if (mInventoryItem) -        { -            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); -            LLUUID parent_id = mInventoryItem->getParentUUID(); -            if (marketplacelistings_id == parent_id) -            { -                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); -            } - -            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle()); -            copy_inventory_item( -                gAgent.getID(), -                mInventoryItem->getPermissions().getOwner(), -                mInventoryItem->getUUID(), -                parent_id, -                settings_name, -                cb); -        } -        else -        { -            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; -        } -    } -} -  void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting)  {      if (!app_quitting) @@ -530,116 +327,6 @@ void LLFloaterFixedEnvironment::onButtonLoad()      checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); });  } -void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) -{ -    if (mInventoryItem) -    { -        LLUUID parent_id = mInventoryItem->getParentUUID(); -        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); -        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    } -    else -    { -        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); -        // This method knows what sort of settings object to create. -        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    } -} - -void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) -{ -    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; -    if (mInventoryId.isNull()) -    { -        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); -    } -    else -    { -        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, -            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); -    } -} - -void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) -{ -    U32 flags(0); - -    if (mInventoryItem) -    { -        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) -            flags |= LLSettingsBase::FLAG_NOMOD; -        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) -            flags |= LLSettingsBase::FLAG_NOTRANS; -    } - -    flags |= settings->getFlags(); -    settings->setFlag(flags); - -    if (where == ACTION_APPLY_LOCAL) -    { -        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. -        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); -    } -    else if (where == ACTION_APPLY_PARCEL) -    { -        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - -        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) -        { -            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; -            LLNotificationsUtil::add("WLParcelApplyFail"); -            return; -        } - -        if (mInventoryItem && !isDirty()) -        { -            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); -        } -        else if (settings->getSettingsType() == "sky") -        { -            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); -        } -        else if (settings->getSettingsType() == "water") -        { -            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); -        } -    } -    else if (where == ACTION_APPLY_REGION) -    { -        if (mInventoryItem && !isDirty()) -        { -            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); -        } -        else if (settings->getSettingsType() == "sky") -        { -            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); -        } -        else if (settings->getSettingsType() == "water") -        { -            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); -        } -    } -    else -    { -        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; -        return; -    } - -} - -void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting) -{ -    LLFloater* floaterp = mInventoryFloater.get(); - -    if (floaterp) -    { -        floaterp->closeFloater(quitting); -    } -} -  void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)  {      LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; @@ -709,28 +396,6 @@ void LLFloaterFixedEnvironment::doSelectFromInventory()      picker->setFocus(TRUE);  } -void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value) -{ -    if (value) -        setDirtyFlag(); -} - -//------------------------------------------------------------------------- -bool LLFloaterFixedEnvironment::canUseInventory() const -{ -    return LLEnvironment::instance().isInventoryEnabled(); -} - -bool LLFloaterFixedEnvironment::canApplyRegion() const -{ -    return gAgent.canManageEstate(); -} - -bool LLFloaterFixedEnvironment::canApplyParcel() const -{ -    return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); -} -  //=========================================================================  LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key):      LLFloaterFixedEnvironment(key) diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index 513996c4a3..f35f4a4368 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -27,7 +27,7 @@  #ifndef LL_FLOATERFIXEDENVIRONMENT_H  #define LL_FLOATERFIXEDENVIRONMENT_H -#include "llfloater.h" +#include "llfloatereditenvironmentbase.h"  #include "llsettingsbase.h"  #include "llflyoutcombobtn.h"  #include "llinventory.h" @@ -43,15 +43,10 @@ class LLFixedSettingCopiedCallback;  /**   * Floater container for creating and editing fixed environment settings.   */ -class LLFloaterFixedEnvironment : public LLFloater +class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase  {      LOG_CLASS(LLFloaterFixedEnvironment); - -    friend class LLFixedSettingCopiedCallback; -  public: -    static const std::string    KEY_INVENTORY_ID; -                              LLFloaterFixedEnvironment(const LLSD &key);                              ~LLFloaterFixedEnvironment(); @@ -59,64 +54,35 @@ public:      virtual void            onOpen(const LLSD& key)     override;      virtual void            onClose(bool app_quitting)  override; -    virtual void            onFocusReceived()           override; -    virtual void            onFocusLost()               override; -      void                    setEditSettings(const LLSettingsBase::ptr_t &settings)  { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); } -    LLSettingsBase::ptr_t   getEditSettings()   const                           { return mSettings; } - -    virtual BOOL            isDirty() const override            { return getIsDirty(); } +    virtual LLSettingsBase::ptr_t getEditSettings()   const override                { return mSettings; }  protected:      typedef std::function<void()> on_confirm_fn; -    virtual void            updateEditEnvironment() = 0;      virtual void            refresh()                   override; +    void                    setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;      virtual void            syncronizeTabs(); -    LLFloaterSettingsPicker *getSettingsPicker(); - -    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true); - -    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb); +    virtual LLFloaterSettingsPicker *getSettingsPicker() override;      LLTabContainer *        mTab;      LLLineEditor *          mTxtName;      LLSettingsBase::ptr_t   mSettings; -    virtual void            doImportFromDisk() = 0; -    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); -    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); -    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); -    void                    doCloseInventoryFloater(bool quitting = false); - -    bool                    canUseInventory() const; -    bool                    canApplyRegion() const; -    bool                    canApplyParcel() const; -      LLFlyoutComboBtnCtrl *      mFlyoutControl; -    LLUUID                  mInventoryId; -    LLInventoryItem *       mInventoryItem; -    LLHandle<LLFloater>     mInventoryFloater; -    bool                    mCanCopy; -    bool                    mCanMod; -    bool                    mCanTrans; -      void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);      void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);      void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); -    bool                    getIsDirty() const  { return mIsDirty; } -    void                    setDirtyFlag()      { mIsDirty = true; } -    virtual void            clearDirtyFlag(); +    virtual void            clearDirtyFlag() override; +    void                    updatePermissionFlags();      void                    doSelectFromInventory(); -    void                    onPanelDirtyFlagChanged(bool);      virtual void            onClickCloseBtn(bool app_quitting = false) override; -    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);  private:      void                    onNameChanged(const std::string &name); @@ -126,9 +92,6 @@ private:      void                    onButtonLoad();      void                    onPickerCommitSetting(LLUUID item_id); -    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); - -    bool                    mIsDirty;  };  class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment @@ -172,36 +135,4 @@ protected:  private:  }; -class LLSettingsEditPanel : public LLPanel -{ -public: -    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; - -    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg; -    typedef boost::signals2::connection connection_t; - -    inline bool         getIsDirty() const      { return mIsDirty; } -    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } -    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } - -    inline bool        getCanChangeSettings() const    { return mCanEdit; } -    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; } - -    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); } - - -protected: -    LLSettingsEditPanel() : -        LLPanel(), -        mIsDirty(false), -        mOnDirtyChanged() -    {} - -private: -    bool                mIsDirty; -    bool                mCanEdit; -     -    on_dirty_charged_sg mOnDirtyChanged; -}; -  #endif // LL_FLOATERFIXEDENVIRONMENT_H diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index c6e9069d09..8d38a5743b 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -309,12 +309,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,  	LLIconCtrl* icon = 0; +	bool is_in_group = gAgent.isInGroup(session_id, TRUE); +	LLUUID icon_id; -	if(gAgent.isInGroup(session_id, TRUE)) +	if (is_in_group)  	{  		LLGroupIconCtrl::Params icon_params;  		icon_params.group_id = session_id;  		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params); +		icon_id = session_id;  		mSessions[session_id] = floaterp;  		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); @@ -326,11 +329,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,  		LLAvatarIconCtrl::Params icon_params;  		icon_params.avatar_id = avatar_id;  		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params); +		icon_id = avatar_id;  		mSessions[session_id] = floaterp;  		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));  	} +	LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id); +	if (floater) +	{ +		floater->updateChatIcon(icon_id); +	} +  	// forced resize of the floater  	LLRect wrapper_rect = this->mTabContainer->getLocalRect();  	floaterp->setRect(wrapper_rect); @@ -1816,6 +1826,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c  		{  			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);  		} + +		// Will destroy views and delete models that are not assigned to any views  		widget->destroyView();  	} diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index d604d0a789..492f63a700 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -32,6 +32,8 @@  #include "llagent.h"  #include "llagentcamera.h"  #include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llgroupiconctrl.h"  #include "llchatentry.h"  #include "llchathistory.h"  #include "llchiclet.h" @@ -45,6 +47,8 @@  #include "llfloaterimnearbychat.h"  const F32 REFRESH_INTERVAL = 1.0f; +const std::string ICN_GROUP("group_chat_icon"); +const std::string ICN_AVATAR("avatar_icon");  void cb_group_do_nothing()  { @@ -342,6 +346,8 @@ BOOL LLFloaterIMSessionTab::postBuild()  	assignResizeLimits(); +	getChild<LLLayoutPanel>("session_icon_layout_panel")->setVisible(mSessionID.notNull()); +  	return result;  } @@ -529,8 +535,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part  	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);  	if (widget)  	{ -		mConversationsRoot->extractItem(widget); -		delete widget; +		widget->destroyView();  	}  	mConversationsWidgets.erase(participant_id);  } @@ -700,6 +705,30 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name)  	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);  } +void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id) +{ +	if (mSession) +	{ +		if (mSession->isP2PSessionType()) +		{ +			LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>(ICN_AVATAR); +			icon->setVisible(true); +			icon->setValue(id); +		} +		if (mSession->isAdHocSessionType()) +		{ +			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP); +			icon->setVisible(true); +		} +		if (mSession->isGroupSessionType()) +		{ +			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP); +			icon->setVisible(true); +			icon->setValue(id); +		} +	} +} +  void LLFloaterIMSessionTab::hideAllStandardButtons()  {  	for (S32 i = 0; i < BUTTON_COUNT; i++) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 5357a14ab9..375461cfc1 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -103,6 +103,8 @@ public:  	void restoreFloater();  	void saveCollapsedState(); +	void updateChatIcon(const LLUUID& id); +  	LLView* getChatHistory();  protected: diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 889d017389..524162ba51 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -103,14 +103,17 @@ void LLPanelMarketplaceListings::buildAllPanels()      panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");  	panel->getFilter().setFilterMarketplaceActiveFolders();  	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); +	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");  	panel->getFilter().markDefault();      panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");  	panel->getFilter().setFilterMarketplaceInactiveFolders();  	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); +	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");  	panel->getFilter().markDefault();      panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");  	panel->getFilter().setFilterMarketplaceUnassociatedFolders();  	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); +	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");  	panel->getFilter().markDefault();      // Set the tab panel diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 481a7dab66..3995d03ea4 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -104,6 +104,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)  void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)  { +	if(LLAppViewer::instance()->quitRequested()) +	{ +		return; +	} +	  	if (filenames.size() > 0)  	{  		mMP->loadModel(filenames[0], mLOD); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index d2bd716f55..12d82d101f 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,6 +39,7 @@  #include "llfloaterimcontainer.h"  #include "llimview.h" // for gIMMgr  #include "llnotificationsutil.h" +#include "llstartup.h"  #include "llstatusbar.h"	// can_afford_transaction()  #include "groupchatlistener.h" @@ -55,6 +56,11 @@ public:  	bool handle(const LLSD& tokens, const LLSD& query_map,  				LLMediaCtrl* web)  	{ +		if (LLStartUp::getStartupState() < STATE_STARTED) +		{ +			return true; +		} +  		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo"))  		{  			LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9afb6ca58b..1059324a16 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -969,6 +969,9 @@ void LLIMModel::LLIMSession::buildHistoryFileName()  			// Incoming P2P sessions include a name that we can use to build a history file name  			mHistoryFileName = LLCacheName::buildUsername(mName);  		} + +        // user's account name can change, but filenames and session names are account name based +        LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName());  	}  	else if (isGroupChat())  	{ diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 72013f7396..2a22eb1329 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -74,6 +74,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)  :	mName(p.name),  	mFilterModified(FILTER_NONE),  	mEmptyLookupMessage("InventoryNoMatchingItems"), +	mDefaultEmptyLookupMessage(""),  	mFilterOps(p.filter_ops),  	mBackupFilterOps(mFilterOps),  	mFilterSubString(p.substring), @@ -1441,12 +1442,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)  	mEmptyLookupMessage = message;  } +void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message) +{ +	mDefaultEmptyLookupMessage = message; +} +  std::string LLInventoryFilter::getEmptyLookupMessage() const  { -	LLStringUtil::format_map_t args; -	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); +	if (isDefault() && !mDefaultEmptyLookupMessage.empty()) +	{ +		return LLTrans::getString(mDefaultEmptyLookupMessage); +	} +	else +	{ +		LLStringUtil::format_map_t args; +		args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); -	return LLTrans::getString(mEmptyLookupMessage, args); +		return LLTrans::getString(mEmptyLookupMessage, args); +	}  } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index be02ee3623..61cc5ae602 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -257,6 +257,7 @@ public:  	EFilterCreatorType		getFilterCreatorType() const;  	void 				setEmptyLookupMessage(const std::string& message); +	void				setDefaultEmptyLookupMessage(const std::string& message);  	std::string			getEmptyLookupMessage() const;  	// +-------------------------------------------------------------------+ @@ -332,6 +333,7 @@ private:  	std::string 			mFilterText;  	std::string 			mEmptyLookupMessage; +	std::string				mDefaultEmptyLookupMessage;  	ESearchType 			mSearchType; diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 2966ca1f10..a25404aaa4 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -107,11 +107,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t              return NULL;          } +        mRequestedList[asset_uuid] = gFrameTimeSeconds; + +        // Note that getAssetData can callback immediately and cleans mRequestedList  		gAssetStorage->getAssetData(asset_uuid,  									LLAssetType::AT_LANDMARK,  									LLLandmarkList::processGetAssetReply,  									NULL); -		mRequestedList[asset_uuid] = gFrameTimeSeconds;  	}  	return NULL;  } @@ -193,11 +195,15 @@ void LLLandmarkList::processGetAssetReply(              landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();              LLUUID asset_uuid = *iter;              gLandmarkList.mWaitList.erase(iter); + +            // add to mRequestedList before calling getAssetData() +            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; + +            // Note that getAssetData can callback immediately and cleans mRequestedList              gAssetStorage->getAssetData(asset_uuid,                  LLAssetType::AT_LANDMARK,                  LLLandmarkList::processGetAssetReply,                  NULL); -            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;          }          scheduling = false;      } diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 415781bc27..eebc2486a2 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -281,6 +281,28 @@ std::string LLLogChat::makeLogFileName(std::string filename)  	return filename;  } +//static +void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename) +{ +    std::string new_name = cleanFileName(new_filename); +    std::string old_name = cleanFileName(old_filename); +    new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name); +    old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name); + +    if (new_name.empty() || old_name.empty()) +    { +        return; +    } + +    new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; +    old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + +    if (!LLFile::isfile(new_name) && LLFile::isfile(old_name)) +    { +        LLFile::rename(old_name, new_name); +    } +} +  std::string LLLogChat::cleanFileName(std::string filename)  {  	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 8b7fe14e16..c4b61ee716 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -94,6 +94,7 @@ public:  	static std::string timestamp(bool withdate = false);  	static std::string makeLogFileName(std::string(filename)); +	static void renameLogFile(const std::string& old_filename, const std::string& new_filename);  	/**  	*Add functions to get old and non date stamped file names when needed  	*/ diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index fa53a21940..e81d2cc082 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -58,6 +58,7 @@  #include "llevents.h"  #include "llappviewer.h"  #include "llsdserialize.h" +#include "lltrans.h"  #include <boost/scoped_ptr.hpp>  #include <sstream> @@ -332,7 +333,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)          {              data["certificate"] = response["certificate"];          } -         +          if (gViewerWindow)              gViewerWindow->setShowProgress(FALSE); @@ -349,13 +350,36 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)          // login.cgi is insisting on a required update. We were called with an          // event that bundles both the login.cgi 'response' and the          // synchronization event from the 'updater'. -        std::string required_version = response["message_args"]["VERSION"]; -        LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL; +        std::string login_version = response["message_args"]["VERSION"]; +        std::string vvm_version   = updater["VERSION"]; +        std::string relnotes      = updater["URL"]; +        LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL; +        // vvm_version might be empty because we might not have gotten +        // SLVersionChecker's LoginSync handshake. But if it IS populated, it +        // should (!) be the same as the version we got from login.cgi. +        if ((! vvm_version.empty()) && vvm_version != login_version) +        { +            LL_WARNS("LLLogin") << "VVM update version " << vvm_version +                                << " differs from login version " << login_version +                                << "; presenting VVM version to match release notes URL" +                                << LL_ENDL; +            login_version = vvm_version; +        } +        if (relnotes.empty() || relnotes.find("://") == std::string::npos) +        { +            relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL"); +            if (!LLStringUtil::endsWith(relnotes, "/")) +                relnotes += "/"; +            relnotes += LLURI::escape(login_version) + ".html"; +        }          if (gViewerWindow)              gViewerWindow->setShowProgress(FALSE); -        LLSD args(LLSDMap("VERSION", required_version)); +        LLSD args; +        args["VERSION"] = login_version; +        args["URL"] = relnotes; +          if (updater.isUndefined())          {              // If the updater failed to shake hands, better advise the user to diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 52c5234137..ef4aced2c7 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -297,6 +297,7 @@ public:  	 * Writes notification message to IM  p2p session.  	 */  	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false); +	static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false);  	/**  	 * Writes group notice notification message to IM  group session. diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 9a3f1a853a..39a0b9b50e 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -123,15 +123,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name  }  // static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only)  {  	if (!gCacheName)  	{  		return;  	} -	LLUUID from_id = notification->getPayload()["from_id"]; -  	if (from_id.isNull())  	{  		// Normal behavior for system generated messages, don't spam. @@ -141,15 +139,22 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi  	if(to_file_only)  	{ -		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); +		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID()));  	}  	else  	{ -		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); +		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id));  	}  }  // static +void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +{ +	LLUUID from_id = notification->getPayload()["from_id"]; +	logToIMP2P(from_id, notification->getMessage(), to_file_only);	 +} + +// static  void LLHandlerUtil::logGroupNoticeToIMGroup(  		const LLNotificationPtr& notification)  { diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 14d25d8158..a9678b1e93 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -37,6 +37,8 @@  #include "llimview.h"  #include "llnotificationsutil.h" +#include <boost/regex.hpp> +  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- @@ -143,7 +145,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)  		{  			// log only to file if notif panel can be embedded to IM and IM is opened  			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); -			LLHandlerUtil::logToIMP2P(notification, file_only); +			if ((notification->getName() == "TeleportOffered" +				|| notification->getName() == "TeleportOffered_MaturityExceeded" +				|| notification->getName() == "TeleportOffered_MaturityBlocked")) +			{ +				boost::regex r("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>( - )?", +					boost::regex::perl|boost::regex::icase); +				std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, ""); +				LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only); +			} +			else +			{ +				LLHandlerUtil::logToIMP2P(notification, file_only); +			}  		}  	} diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index c02c9c95a0..801fb8b9b2 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -29,7 +29,7 @@  #include "llpanel.h"  #include "llsettingssky.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h"  //=========================================================================  class LLSlider; diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h index ab2dc47bcc..4b7ec903c9 100644 --- a/indra/newview/llpaneleditwater.h +++ b/indra/newview/llpaneleditwater.h @@ -30,7 +30,7 @@  #include "llpanel.h"  #include "llsettingswater.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h"  //=========================================================================  class LLSlider; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 4f60703488..3964dc075c 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -545,6 +545,16 @@ void LLPanelLogin::show(const LLRect &rect,  }  //static +void LLPanelLogin::reshapePanel() +{ +    if (sInstance) +    { +        LLRect rect = sInstance->getRect(); +        sInstance->reshape(rect.getWidth(), rect.getHeight()); +    } +} + +//static  void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)  {      if (!sInstance) diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index c9b8e1b6fc..788c269ffd 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -54,6 +54,7 @@ public:  	static void show(const LLRect &rect,  		void (*callback)(S32 option, void* user_data),   		void* callback_data); +	static void reshapePanel();  	static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);  	static void resetFields(); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index c39df3fe8b..4762e15d8f 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -37,6 +37,7 @@  #include "llfloatersidepanelcontainer.h"  #include "llfloaterworldmap.h"  #include "llnotificationsutil.h" +#include "llstartup.h"  #include "lltexturectrl.h"  #include "lltoggleablemenu.h"  #include "lltrans.h" @@ -84,6 +85,11 @@ public:  	bool handle(const LLSD& params, const LLSD& query_map,  		LLMediaCtrl* web)  	{ +		if (LLStartUp::getStartupState() < STATE_STARTED) +		{ +			return true; +		} +  		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))  		{  			LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); @@ -198,6 +204,11 @@ public:  	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)  	{ +		if (LLStartUp::getStartupState() < STATE_STARTED) +		{ +			return true; +		} +  		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))  		{  			LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 2bd78f40ba..c42cd6c6ba 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -74,6 +74,8 @@ const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels  const int LLPanelPrimMediaControls::kNumZoomLevels = 2;  const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f; +const S32 ADDR_LEFT_PAD = 3; +  //  // LLPanelPrimMediaControls  // @@ -156,7 +158,7 @@ BOOL LLPanelPrimMediaControls::postBuild()  	mMediaProgressPanel		= getChild<LLPanel>("media_progress_indicator");  	mMediaProgressBar		= getChild<LLProgressBar>("media_progress_bar");  	mMediaAddressCtrl		= getChild<LLUICtrl>("media_address"); -	mMediaAddress			= getChild<LLUICtrl>("media_address_url"); +	mMediaAddress			= getChild<LLLineEditor>("media_address_url");  	mMediaPlaySliderPanel	= getChild<LLUICtrl>("media_play_position");  	mMediaPlaySliderCtrl	= getChild<LLUICtrl>("media_play_slider");  	mSkipFwdCtrl			= getChild<LLUICtrl>("skip_forward"); @@ -501,8 +503,10 @@ void LLPanelPrimMediaControls::updateShape()  			std::string test_prefix = mCurrentURL.substr(0, prefix.length());  			LLStringUtil::toLower(test_prefix);              mSecureURL = has_focus && (test_prefix == prefix); -            mCurrentURL = (mSecureURL ? "      " + mCurrentURL : mCurrentURL); -			 + +			S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD; +			mMediaAddress->setTextPadding(left_pad, 0); +  			if(mCurrentURL!=mPreviousURL)  			{  				setCurrentURL(); diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 86fc036553..dd0e4ff095 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -39,6 +39,7 @@ class LLProgressBar;  class LLSliderCtrl;  class LLViewerMediaImpl;  class LLWindowShade; +class LLLineEditor;  class LLPanelPrimMediaControls : public LLPanel  { @@ -164,7 +165,7 @@ private:  	LLPanel  *mMediaProgressPanel;  	LLProgressBar *mMediaProgressBar;  	LLUICtrl *mMediaAddressCtrl; -	LLUICtrl *mMediaAddress; +	LLLineEditor *mMediaAddress;  	LLUICtrl *mMediaPlaySliderPanel;  	LLUICtrl *mMediaPlaySliderCtrl;  	LLUICtrl *mVolumeCtrl; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index ee6893907e..94d20828ec 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -259,11 +259,7 @@ LLParticipantList::~LLParticipantList()  */  void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)  { -	LLConversationItemParticipant* participant = findParticipant(participant_id); -	if (participant) -	{ -		removeParticipant(participant); -	} +	removeParticipant(participant_id);  	// re-add avaline caller with a correct class instance.  	addAvatarIDExceptAgent(participant_id);  } @@ -397,6 +393,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)  	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))  	// Add the participant model to the session's children list +	// This will post "add_participant" event  	addParticipant(participant);  	adjustParticipant(avatar_id); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 379bc9871c..1a579556ad 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -733,7 +733,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)  		}  		if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME))  		{ -			std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); +			// Use Wtext since segment's start/end are made for wstring and will +			// result in a shift for case of multi-byte symbols inside std::string. +			LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); +			std::string help_string = wstring_to_utf8str(segment_text);  			setHelpPage(help_string);  			mLiveHelpTimer.stop();  		} diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 3c9ce6b752..f9baf5fbd3 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -530,157 +530,163 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  	if (!hasResults()) return;  	LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;  - -	llofstream os(file_name.c_str()); - -	os << std::setprecision(10); - -	LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); -	const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - -	F64Seconds frame_time; - -	os << "Stat"; -	for (S32 frame = 1; frame <= frame_count; frame++) +	try  	{ -		frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); -		os << ", " << frame_time.value(); -	} -	os << '\n'; +		llofstream os(file_name.c_str()); -	os << "Sample period(s)"; -	for (S32 frame = 1; frame <= frame_count; frame++) -	{ -		frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); -		os << ", " << frame_time.value(); -	} -	os << '\n'; +		os << std::setprecision(10); +		LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); +		const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); -	typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count; -	for (auto& it : trace_count::instance_snapshot()) -	{ -		std::ostringstream row; -		row << std::setprecision(10); +		F64Seconds frame_time; -		row << it.getName(); - -		const char* unit_label = it.getUnitLabel(); -		if(unit_label[0]) +		os << "Stat"; +		for (S32 frame = 1; frame <= frame_count; frame++)  		{ -			row << "(" << unit_label << ")"; +			frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); +			os << ", " << frame_time.value();  		} +		os << '\n'; -		S32 samples = 0; - +		os << "Sample period(s)";  		for (S32 frame = 1; frame <= frame_count; frame++)  		{ -			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); -			samples += recording.getSampleCount(it); -			row << ", " << recording.getSum(it); +			frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); +			os << ", " << frame_time.value();  		} +		os << '\n'; -		row << '\n'; -		if (samples > 0) +		typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count; +		for (auto& it : trace_count::instance_snapshot())  		{ -			os << row.str(); -		} -	} - -	typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event; +			std::ostringstream row; +			row << std::setprecision(10); -	for (auto& it : trace_event::instance_snapshot()) -	{ -		std::ostringstream row; -		row << std::setprecision(10); -		row << it.getName(); +			row << it.getName(); -		const char* unit_label = it.getUnitLabel(); -		if(unit_label[0]) -		{ -			row << "(" << unit_label << ")"; -		} +			const char* unit_label = it.getUnitLabel(); +			if (unit_label[0]) +			{ +				row << "(" << unit_label << ")"; +			} -		S32 samples = 0; +			S32 samples = 0; -		for (S32 frame = 1; frame <= frame_count; frame++) -		{ -			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); -			samples += recording.getSampleCount(it); -			F64 mean = recording.getMean(it); -			if (llisnan(mean)) +			for (S32 frame = 1; frame <= frame_count; frame++)  			{ -				row << ", n/a"; +				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); +				samples += recording.getSampleCount(it); +				row << ", " << recording.getSum(it);  			} -			else + +			row << '\n'; + +			if (samples > 0)  			{ -				row << ", " << mean; +				os << row.str();  			}  		} -		row << '\n'; +		typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event; -		if (samples > 0) +		for (auto& it : trace_event::instance_snapshot())  		{ -			os << row.str(); -		} -	} +			std::ostringstream row; +			row << std::setprecision(10); +			row << it.getName(); -	typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample; +			const char* unit_label = it.getUnitLabel(); +			if (unit_label[0]) +			{ +				row << "(" << unit_label << ")"; +			} -	for (auto& it : trace_sample::instance_snapshot()) -	{ -		std::ostringstream row; -		row << std::setprecision(10); -		row << it.getName(); +			S32 samples = 0; -		const char* unit_label = it.getUnitLabel(); -		if(unit_label[0]) -		{ -			row << "(" << unit_label << ")"; +			for (S32 frame = 1; frame <= frame_count; frame++) +			{ +				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); +				samples += recording.getSampleCount(it); +				F64 mean = recording.getMean(it); +				if (llisnan(mean)) +				{ +					row << ", n/a"; +				} +				else +				{ +					row << ", " << mean; +				} +			} + +			row << '\n'; + +			if (samples > 0) +			{ +				os << row.str(); +			}  		} -		S32 samples = 0; +		typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample; -		for (S32 frame = 1; frame <= frame_count; frame++) +		for (auto& it : trace_sample::instance_snapshot())  		{ -			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); -			samples += recording.getSampleCount(it); -			F64 mean = recording.getMean(it); -			if (llisnan(mean)) +			std::ostringstream row; +			row << std::setprecision(10); +			row << it.getName(); + +			const char* unit_label = it.getUnitLabel(); +			if (unit_label[0]) +			{ +				row << "(" << unit_label << ")"; +			} + +			S32 samples = 0; + +			for (S32 frame = 1; frame <= frame_count; frame++)  			{ -				row << ", n/a"; +				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); +				samples += recording.getSampleCount(it); +				F64 mean = recording.getMean(it); +				if (llisnan(mean)) +				{ +					row << ", n/a"; +				} +				else +				{ +					row << ", " << mean; +				}  			} -			else + +			row << '\n'; + +			if (samples > 0)  			{ -				row << ", " << mean; +				os << row.str();  			}  		} -		row << '\n';  - -		if (samples > 0) +		typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem; +		for (auto& it : trace_mem::instance_snapshot())  		{ -			os << row.str(); -		} -	} +			os << it.getName() << "(KiB)"; -	typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem; -	for (auto& it : trace_mem::instance_snapshot()) -	{ -		os << it.getName() << "(KiB)"; +			for (S32 frame = 1; frame <= frame_count; frame++) +			{ +				os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>(); +			} -		for (S32 frame = 1; frame <= frame_count; frame++) -		{ -			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>(); +			os << '\n';  		} -		os << '\n'; +		os.flush(); +		os.close(); +	} +	catch (const std::ios_base::failure &e) +	{ +		LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL;  	} - -	os.flush(); -	os.close();  }  //------------------------------------------------------------------------------------------------------------- diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f281b30a8e..b4cb3a1740 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3529,11 +3529,6 @@ bool process_login_success_response()  	}  	// Request the map server url -	// Non-agni grids have a different default location. -	if (!LLGridManager::getInstance()->isInProductionGrid()) -	{ -		gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/"); -	}  	std::string map_server_url = response["map-server-url"];  	if(!map_server_url.empty())  	{ diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 5b76d57196..8bf6ad16d2 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -48,8 +48,8 @@  /// LLViewerAssetRequest  ///---------------------------------------------------------------------------- - // There is also PoolSizeVAssetStorage value in setting that should mirror this name -static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage"; + // There is also PoolSizeAssetStorage value in setting that should mirror this name +static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage";  /**   * @brief Local class to encapsulate asset fetch requests with a timestamp. @@ -132,6 +132,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage()          // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later.           LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL);      } + +    while (mCoroWaitList.size() > 0) +    { +        CoroWaitList &request = mCoroWaitList.front(); +        // Clean up pending downloads, delete request and trigger callbacks +        removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); +        mCoroWaitList.pop_front(); +    }  }  // virtual  @@ -336,6 +344,27 @@ void LLViewerAssetStorage::storeAssetData(      }  } +void LLViewerAssetStorage::checkForTimeouts() +{ +    LLAssetStorage::checkForTimeouts(); + +    // Restore requests +    LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); +    while (mCoroWaitList.size() > 0 +           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) +    { +        CoroWaitList &request = mCoroWaitList.front(); +         +        bool with_http = true; +        bool is_temp = false; +        LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); + +        manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", +            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); + +        mCoroWaitList.pop_front(); +    } +}  /**   * @brief Allocate and queue an asset fetch request for the viewer @@ -393,12 +422,20 @@ void LLViewerAssetStorage::queueRequestHttp(      // This is the same as the current UDP logic - don't re-request a duplicate.      if (!duplicate)      { -        bool with_http = true; -        bool is_temp = false; -        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); +        // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit +        if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) +        { +            bool with_http = true; +            bool is_temp = false; +            LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); -        LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro", -            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +            LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", +                boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +        } +        else +        { +            mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); +        }      }  } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 972c89de34..af7fbb5fbf 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -43,7 +43,7 @@ public:  	~LLViewerAssetStorage(); -	virtual void storeAssetData( +	void storeAssetData(  		const LLTransactionID& tid,  		LLAssetType::EType atype,  		LLStoreAssetCallback callback, @@ -52,9 +52,9 @@ public:  		bool is_priority = false,  		bool store_local = false,  		bool user_waiting=FALSE, -		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); -	 -	virtual void storeAssetData( +		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + +	void storeAssetData(  		const std::string& filename,  		const LLTransactionID& tid,  		LLAssetType::EType type, @@ -63,16 +63,17 @@ public:  		bool temp_file = false,  		bool is_priority = false,  		bool user_waiting=FALSE, -		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); +		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + +    void checkForTimeouts() override;  protected: -	// virtual  	void _queueDataRequest(const LLUUID& uuid,  						   LLAssetType::EType type,                             LLGetAssetCallback callback,  						   void *user_data,  						   BOOL duplicate, -						   BOOL is_priority); +						   BOOL is_priority) override;      void queueRequestHttp(const LLUUID& uuid,                            LLAssetType::EType type, @@ -91,8 +92,35 @@ protected:      std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); -    void logAssetStorageInfo(); -     +    void logAssetStorageInfo() override; + +    // Asset storage works through coroutines and coroutines have limited queue capacity +    // This class is meant to temporary store requests when fiber's queue is full +    class CoroWaitList +    { +    public: +        CoroWaitList(LLViewerAssetRequest *req, +            const LLUUID& uuid, +            LLAssetType::EType atype, +            LLGetAssetCallback &callback, +            void *user_data) +          : mRequest(req), +            mId(uuid), +            mType(atype), +            mCallback(callback), +            mUserData(user_data) +        { +        } + +        LLViewerAssetRequest* mRequest; +        LLUUID mId; +        LLAssetType::EType mType; +        LLGetAssetCallback mCallback; +        void *mUserData; +    }; +    typedef std::list<CoroWaitList> wait_list_t; +    wait_list_t mCoroWaitList; +      std::string mViewerAssetUrl;      S32 mAssetCoroCount;      S32 mCountRequests; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0404a8056a..a55ff8560c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5394,7 +5394,7 @@ class LLToolsSelectNextPartFace : public view_listener_t                          new_te = to_select->getNumTEs() - 1;                      }                  } -                LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE); +                LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);              }              else              { diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index a593905060..be05ac0d3a 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -130,7 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file)  				  "https://secondlife.aditi.lindenlab.com/helpers/",  				  DEFAULT_LOGIN_PAGE,  				  SL_UPDATE_QUERY_URL, -				  "https://my.aditi.lindenlab.com/", +				  "https://my.secondlife-beta.com/",  				  "Aditi");  	LLSD other_grids; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b88baf6aa7..395dd0495f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4880,22 +4880,78 @@ void LLViewerObject::refreshBakeTexture()  	}  } +void LLViewerObject::updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture) +{ +    // Objects getting non-alpha texture and alpha mask can result in graphical bugs, like white or red alphas. +    // To resolve the issue this function provides image format to material and based on format material's +    // getDiffuseAlphaModeRender() function will decide what value to provide to render +    // +    // Unfortunately LLMaterial has no access to diffuse image, so we have to set this data in LLViewerObject +    // regardles of object being used/seen or frequency of image-updates. +    mat->setDiffuseBaked(baked_texture); + +    if (!baked_texture) +    { +        if (imagep->isMissingAsset()) +        { +            mat->setDiffuseFormatPrimary(0); +        } +        else if (0 == imagep->getPrimaryFormat()) +        { +            // We don't have information about this texture, wait for it +            mWaitingTextureInfo.insert(uuid_material_mmap_t::value_type(imagep->getID(), material_info(LLRender::DIFFUSE_MAP, te))); +            // Temporary assume RGBA image +            mat->setDiffuseFormatPrimary(GL_RGBA); +        } +        else +        { +            mat->setDiffuseFormatPrimary(imagep->getPrimaryFormat()); +        } +    } +} + +S32 LLViewerObject::setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep) +{ +    LLUUID new_id = imagep->getID(); +    S32 retval = LLPrimitive::setTETexture(te, new_id); + +    LLTextureEntry* tep = getTE(te); +    LLUUID old_image_id = tep->getID(); + +    LLViewerTexture* baked_texture = getBakedTextureForMagicId(new_id); +    mTEImages[te] = baked_texture ? baked_texture : imagep; +    updateAvatarMeshVisibility(new_id, old_image_id); + +    LLMaterial* mat = tep->getMaterialParams(); +    if (mat) +    { +        // Don't update format from texture (and don't shedule one) if material has no alpha mode set, +        // just assume RGBA format, format will get updated with setTEMaterialParams call if mode changes +        if (mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) +        { +            bool baked = baked_texture != NULL; +            updateDiffuseMatParams(te, mat, imagep, baked); +        } +        else +        { +            mat->setDiffuseFormatPrimary(GL_RGBA); +        } +    } + +    setChanged(TEXTURE); +    if (mDrawable.notNull()) +    { +        gPipeline.markTextured(mDrawable); +    } + +    return retval; +} +  void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)  {  	if (mTEImages[te] != imagep)  	{ -		LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; -		 -		LLPrimitive::setTETexture(te, imagep->getID()); - -		LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); -		mTEImages[te] = baked_texture ? baked_texture : imagep; -		updateAvatarMeshVisibility(imagep->getID(), old_image_id); -		setChanged(TEXTURE); -		if (mDrawable.notNull()) -		{ -			gPipeline.markTextured(mDrawable); -		} +        setDiffuseImageAndParams(te, imagep);  	}  } @@ -4907,15 +4963,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)  	if (uuid != getTE(te)->getID() ||  		uuid == LLUUID::null)  	{ -		retval = LLPrimitive::setTETexture(te, uuid); -		LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); -		mTEImages[te] = baked_texture ? baked_texture : image; -		updateAvatarMeshVisibility(uuid,old_image_id); -		setChanged(TEXTURE); -		if (mDrawable.notNull()) -		{ -			gPipeline.markTextured(mDrawable); -		} +		retval = setDiffuseImageAndParams(te, image);  	}  	return retval;  } @@ -5210,6 +5258,29 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri  		return 0;  	} +    if (pMaterialParams.notNull() +        && pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) +    { +        // Don't update if no alpha is set. If alpha changes, this function will run again, +        // no point in sheduling additional texture callbacks (in updateDiffuseMatParams) +        LLTextureEntry* tex_entry = getTE(te); +        bool is_baked = tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()); + +        LLViewerTexture *img_diffuse = getTEImage(te); +        llassert(NULL != img_diffuse); + +        if (NULL != img_diffuse) +        { +            // Will modify alpha mask provided to renderer to fit image +            updateDiffuseMatParams(te, pMaterialParams.get(), img_diffuse, is_baked); +        } +        else +        { +            LLMaterial *mat = pMaterialParams.get(); // to avoid const +            mat->setDiffuseFormatPrimary(0); +        } +    } +  	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);  	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te  							<< ", object " << mID @@ -5222,6 +5293,84 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri  	return retval;  } +bool LLViewerObject::notifyAboutCreatingTexture(LLViewerTexture *texture) +{ +    // Confirmation about texture creation, check wait-list +    // and make changes, or return false + +    std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); + +    bool refresh_materials = false; + +    // RGB textures without alpha channels won't work right with alpha, +    // we provide format to material for material to decide when to drop alpha +    for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) +    { +        LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); +        if (cur_material.notNull() +            && LLRender::DIFFUSE_MAP == range_it->second.map) +        { +            U32 format = texture->getPrimaryFormat(); +            if (format != cur_material->getDiffuseFormatPrimary()) +            { +                cur_material->setDiffuseFormatPrimary(format); +                refresh_materials = true; +            } +        } +    } //for + +    if (refresh_materials) +    { +        LLViewerObject::refreshMaterials(); +    } + +    //clear wait-list +    mWaitingTextureInfo.erase(range.first, range.second); + +    return refresh_materials; +} + +bool LLViewerObject::notifyAboutMissingAsset(LLViewerTexture *texture) +{ +    // When waiting information about texture it turned out to be missing. +    // Confirm the state, update values accordingly +    std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); +    if (range.first == range.second) return false; + +    bool refresh_materials = false; + +    for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) +    { +        LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); +        if (cur_material.isNull()) +            continue; + +        if (range_it->second.map == LLRender::DIFFUSE_MAP) +        { +            LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); +            if (cur_material.notNull() +                && LLRender::DIFFUSE_MAP == range_it->second.map) +            { +                if (0 != cur_material->getDiffuseFormatPrimary()) +                { +                    cur_material->setDiffuseFormatPrimary(0); +                    refresh_materials = true; +                } +            } +        } +    } //for + +    if (refresh_materials) +    { +        LLViewerObject::refreshMaterials(); +    } + +    //clear wait-list +    mWaitingTextureInfo.erase(range.first, range.second); + +    return refresh_materials; +} +  void LLViewerObject::refreshMaterials()  {  	setChanged(TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 250c4ac328..9444c4f788 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -768,7 +768,12 @@ protected:  	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);  	void deleteParticleSource();  	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); -	 + +    // Helper function to modify alpha mask provided to render according to image (ex: RGB image will drop alpha mask) +    void updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture); +    // Shared part of code from setTEImage and setTETextureCore +    S32 setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep); +  private:  	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string  	void deleteTEImages(); // correctly deletes list of images @@ -901,10 +906,27 @@ public:      LLJointRiggingInfoTab mJointRiggingInfoTab; +    bool notifyAboutCreatingTexture(LLViewerTexture *texture); +    bool notifyAboutMissingAsset(LLViewerTexture *texture); +  private:  	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.  	EObjectUpdateType	mLastUpdateType;  	BOOL	mLastUpdateCached; + +    struct material_info +    { +        LLRender::eTexIndex map; +        U8 te; + +        material_info(LLRender::eTexIndex map_, U8 te_) +            : map(map_) +            , te(te_) +        {} +    }; + +    typedef std::multimap<LLUUID, material_info> uuid_material_mmap_t; +    uuid_material_mmap_t mWaitingTextureInfo;  };  /////////////////// diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index bea4f2e4a5..cb37f268f2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2323,7 +2323,6 @@ void LLViewerWindow::shutdownGL()  LLViewerWindow::~LLViewerWindow()  {  	LL_INFOS() << "Destroying Window" << LL_ENDL; -	gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes  	destroyWindow();  	delete mDebugText; @@ -2414,6 +2413,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)  		// round up when converting coordinates to make sure there are no gaps at edge of window  		LLView::sForceReshape = display_scale_changed;  		mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY])); +        if (display_scale_changed) +        { +            // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass() +            LLPanelLogin::reshapePanel(); +        }  		LLView::sForceReshape = FALSE;  		// clear font width caches diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 377f3174f3..06e20038c5 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -180,6 +180,13 @@ void LLVoiceClient::terminate()  {  	if (mVoiceModule) mVoiceModule->terminate();  	mVoiceModule = NULL; +    m_servicePump = NULL; + +    // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it +    if (LLSpeakerVolumeStorage::instanceExists()) +    { +        LLSpeakerVolumeStorage::deleteSingleton(); +    }  }  const LLVoiceVersionInfo LLVoiceClient::getVersion() diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index a8d668420e..f9ffefd4a2 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -391,7 +391,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()  void LLVivoxVoiceClient::init(LLPumpIO *pump)  {  	// constructor will set up LLVoiceClient::getInstance() -	LLVivoxVoiceClient::getInstance()->mPump = pump; +	mPump = pump;  //     LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",  //         boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); @@ -419,6 +419,7 @@ void LLVivoxVoiceClient::terminate()  	}      sShuttingDown = true; +    mPump = NULL;  }  //--------------------------------------------------- @@ -953,10 +954,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()      llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); -    while (!mPump) -    {   // Can't do this until we have the pump available. +    while (!mPump && !sShuttingDown) +    {   // Can't use the pump until we have it available.          llcoro::suspend();      } + +    if (sShuttingDown) +    { +        return false; +    }      // MBW -- Note to self: pumps and pipes examples in      //  indra/test/io.cpp @@ -969,8 +975,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()      readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket)));      readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser())); +      mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); +      //---------------------------------------------------------------------      llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); @@ -993,6 +1001,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()          // *TODO* Pump a message for wake up.          llcoro::suspend();      } +     +    if (sShuttingDown) +    { +        return false; +    }      std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest"); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 8e46ccd555..41099cb570 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -45,6 +45,8 @@  #include "llviewertexturelist.h"  #include "llviewerobjectlist.h"  #include "llviewerregion.h" +#include "llvolumemgr.h" +#include "llvovolume.h"  #include "llworld.h"  #include "noise.h"  #include "pipeline.h" @@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region  	mFrameCount = 0;  	mWind = mRegionp->mWind.getVelocity(getPositionRegion());  	mTrunkLOD = 0; + +	// if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels +	llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS);  } @@ -347,8 +352,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)  		return;  	} -	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; +	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled  	F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; +	F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f); +	F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter +	F32 sz = mBillboardScale * mBillboardRatio * diameter;  	for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)  	{ @@ -357,7 +365,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)  			trunk_LOD = j;  			break;  		} -	}  +	} + +    F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance; +    S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality + +    // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels +    trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1); +    trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS);  	if (mReferenceBuffer.isNull())  	{ @@ -408,8 +423,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)  	LLVector3 lookAt = center - viewer_pos_agent;  	F32 dist = lookAt.normVec() ;	  	F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;	 -	 -	F32 range = dist - getMinScale()/2; +	F32 radius = getScale().length()*0.5f; +	F32 range = dist - radius; +  	if (range < F_ALMOST_ZERO || isHUDAttachment())		// range == zero  	{  		mAppAngle = 180.f; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 95cfe29a80..2d1a882a7e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2295,244 +2295,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)  	return res;  } -bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture) -{ //Ok, here we have confirmation about texture creation, check our wait-list -  //and make changes, or return false - -	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); - -	typedef std::map<U8, LLMaterialPtr> map_te_material; -	map_te_material new_material; - -	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) -	{ -		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - -		//here we just interesting in DIFFUSE_MAP only! -		if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat()) -		{ //ok let's check the diffuse mode -			switch(cur_material->getDiffuseAlphaMode()) -			{ -			case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: -			case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: -			case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: -				{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - -					LLMaterialPtr mat = NULL; -					map_te_material::iterator it = new_material.find(range_it->second.te); -					if(new_material.end() == it) { -						mat = new LLMaterial(cur_material->asLLSD()); -						new_material.insert(map_te_material::value_type(range_it->second.te, mat)); -					} else { -						mat = it->second; -					} - -					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - -				} break; -			} //switch -		} //if -	} //for - -	//setup new materials -	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) -	{ -		// These are placeholder materials, they shouldn't be sent to server -		LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second); -		LLViewerObject::setTEMaterialParams(it->first, it->second); -	} - -	//clear wait-list -	mWaitingTextureInfo.erase(range.first, range.second); - -	return 0 != new_material.size(); -} - -bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) -{ //Ok, here if we wait information about texture and it's missing -  //then depending from the texture map (diffuse, normal, or specular) -  //make changes in material and confirm it. If not return false. -	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); -	if(range.first == range.second) return false; - -	typedef std::map<U8, LLMaterialPtr> map_te_material; -	map_te_material new_material; -	 -	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) -	{ -		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); -		if (cur_material.isNull()) -			continue; - -		switch(range_it->second.map) -		{ -		case LLRender::DIFFUSE_MAP: -			{ -				if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode()) -				{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE -					LLMaterialPtr mat = NULL; -					map_te_material::iterator it = new_material.find(range_it->second.te); -					if(new_material.end() == it) { -						mat = new LLMaterial(cur_material->asLLSD()); -						new_material.insert(map_te_material::value_type(range_it->second.te, mat)); -					} else { -						mat = it->second; -					} - -					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); -				} -			} break; -		case LLRender::NORMAL_MAP: -			{ //missing texture => reset material texture id -				LLMaterialPtr mat = NULL; -				map_te_material::iterator it = new_material.find(range_it->second.te); -				if(new_material.end() == it) { -					mat = new LLMaterial(cur_material->asLLSD()); -					new_material.insert(map_te_material::value_type(range_it->second.te, mat)); -				} else { -					mat = it->second; -				} - -				mat->setNormalID(LLUUID::null); -			} break; -		case LLRender::SPECULAR_MAP: -			{ //missing texture => reset material texture id -				LLMaterialPtr mat = NULL; -				map_te_material::iterator it = new_material.find(range_it->second.te); -				if(new_material.end() == it) { -					mat = new LLMaterial(cur_material->asLLSD()); -					new_material.insert(map_te_material::value_type(range_it->second.te, mat)); -				} else { -					mat = it->second; -				} - -				mat->setSpecularID(LLUUID::null); -			} break; -		case LLRender::NUM_TEXTURE_CHANNELS: -				//nothing to do, make compiler happy -			break; -		} //switch -	} //for - -	//setup new materials -	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) -	{ -		LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second); -		LLViewerObject::setTEMaterialParams(it->first, it->second); -	} - -	//clear wait-list -	mWaitingTextureInfo.erase(range.first, range.second); - -	return 0 != new_material.size(); -} -  S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)  { -	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams); - -	if(pMaterialParams) -	{ //check all of them according to material settings - -		LLViewerTexture *img_diffuse = getTEImage(te); -		LLViewerTexture *img_normal = getTENormalMap(te); -		LLViewerTexture *img_specular = getTESpecularMap(te); - -		llassert(NULL != img_diffuse); - -		LLMaterialPtr new_material = NULL; - -		//diffuse -		if(NULL != img_diffuse) -		{ //guard -			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset()) -			{ //ok here we don't have information about texture, let's belief and leave material settings -			  //but we remember this case -				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te))); -			} -			else -			{ -				bool bSetDiffuseNone = false; -				if(img_diffuse->isMissingAsset()) -				{ -					bSetDiffuseNone = true; -				} -				else -				{ -					switch(pMaterialParams->getDiffuseAlphaMode()) -					{ -					case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: -					case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: -					case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: -						{ //all of them modes available only for 32 bit textures -							LLTextureEntry* tex_entry = getTE(te); -							bool bIsBakedImageId = false; -							if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) -							{ -								bIsBakedImageId = true; -							} -							if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId) -							{ -								bSetDiffuseNone = true; -							} -						} break; -					} -				} //else - - -				if(bSetDiffuseNone) -				{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE -					new_material = new LLMaterial(pMaterialParams->asLLSD()); -					new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); -				} -			} -		} - -		//normal -		if(LLUUID::null != pMaterialParams->getNormalID()) -		{ -			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID()) -			{ -				if(!new_material) { -					new_material = new LLMaterial(pMaterialParams->asLLSD()); -				} -				new_material->setNormalID(LLUUID::null); -			} -			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat()) -			{ //ok here we don't have information about texture, let's belief and leave material settings -				//but we remember this case -				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te))); -			} - -		} - - -		//specular -		if(LLUUID::null != pMaterialParams->getSpecularID()) -		{ -			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID()) -			{ -				if(!new_material) { -					new_material = new LLMaterial(pMaterialParams->asLLSD()); -				} -				new_material->setSpecularID(LLUUID::null); -			} -			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat()) -			{ //ok here we don't have information about texture, let's belief and leave material settings -				//but we remember this case -				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te))); -			} -		} - -		if(new_material) { -			pMaterial = new_material; -			LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial); -		} -	} - -	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial); +	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); -	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res +	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res  							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )  							 << LL_ENDL;  	setChanged(ALL_CHANGED); @@ -4599,7 +4366,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&  					LLMaterial* mat = te->getMaterialParams();  					if (mat)  					{ -						U8 mode = mat->getDiffuseAlphaMode(); +						U8 mode = mat->getDiffuseAlphaModeRender();  						if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE  							|| mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE @@ -5245,7 +5012,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			}  			draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); -			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); +			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaModeRender();  			draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());  		}  		else  @@ -5607,7 +5374,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						if (mat && LLPipeline::sRenderDeferred)  						{ -							U8 alpha_mode = mat->getDiffuseAlphaMode(); +							U8 alpha_mode = mat->getDiffuseAlphaModeRender();  							bool is_alpha = type == LLDrawPool::POOL_ALPHA &&  								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || @@ -5636,7 +5403,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						else if (mat)  						{							  							bool is_alpha = type == LLDrawPool::POOL_ALPHA; -							U8 mode = mat->getDiffuseAlphaMode(); +							U8 mode = mat->getDiffuseAlphaModeRender();  							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||  												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; @@ -6534,7 +6301,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  			bool can_be_shiny = true;  			if (mat)  			{ -				U8 mode = mat->getDiffuseAlphaMode(); +				U8 mode = mat->getDiffuseAlphaModeRender();  				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||  								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;  			} @@ -6556,7 +6323,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				//  				if (te->getFullbright())  				{ -					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  					{  						if (opaque)  						{ @@ -6641,7 +6408,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  			}  			else if (mat)  			{ -				U8 mode = mat->getDiffuseAlphaMode(); +				U8 mode = mat->getDiffuseAlphaModeRender();                  is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); @@ -6740,7 +6507,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				}  				else if (fullbright || bake_sunlight)  				{ //fullbright -					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  					{  						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);  					} @@ -6762,7 +6529,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  					else  					{ //all around simple  						llassert(mask & LLVertexBuffer::MAP_NORMAL); -						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +						if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  						{ //material alpha mask can be respected in non-deferred  							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);  						} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 73eeec813c..768af59747 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -440,26 +440,6 @@ protected:  	static S32 sNumLODChanges;  	friend class LLVolumeImplFlexible; - -public: -	bool notifyAboutCreatingTexture(LLViewerTexture *texture); -	bool notifyAboutMissingAsset(LLViewerTexture *texture); - -private: -	struct material_info  -	{ -		LLRender::eTexIndex map; -		U8 te; - -		material_info(LLRender::eTexIndex map_, U8 te_) -			: map(map_) -			, te(te_) -		{} -	}; - -	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t; -	mmap_UUID_MAP_t	mWaitingTextureInfo; -  };  #endif // LL_LLVOVOLUME_H diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7ba7e545f4..bd667acb53 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1677,7 +1677,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima  	if (alpha && mat)  	{ -		switch (mat->getDiffuseAlphaMode()) +		switch (mat->getDiffuseAlphaModeRender())  		{  			case 1:  				alpha = true; // Material's alpha mode is set to blend.  Toss it into the alpha draw pool. diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e1cf708094..efe8102f83 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -337,6 +337,9 @@       name="ContextSilhouetteColor"       reference="EmphasisColor" />      <color +     name="ConversationFriendColor" +     value="0.42 0.85 0.71 1" /> +    <color       name="DefaultHighlightDark"       reference="White_10" />      <color diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.pngBinary files differ index 5ac4258b9d..2cb577776d 100644 --- a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png +++ b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml index 49be4290c7..1f7d52dbf5 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml @@ -32,6 +32,10 @@       name="no_transfer_text">          (no transfer)      </floater.string> +    <floater.string +      name="mupliple_selected"> +        Mupliple selection +    </floater.string>      <scroll_list       background_visible="true"       draw_border="false" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index c64ee5565a..f61e5f1acc 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -266,6 +266,31 @@                   left="0"                   right="-1">                      <layout_panel +                     auto_resize="false" +                     name="session_icon_layout_panel" +                     width="24"> +                      <avatar_icon +                       follows="left|bottom" +                       name="avatar_icon" +                       height="20" +                       default_icon_name="Generic_Person" +                       layout="topleft" +                       left="3" +                       bottom="-9" +                       visible="false" +                       width="20" /> +                      <group_icon +                       follows="left|bottom" +                       name="group_chat_icon" +                       height="20" +                       default_icon_name="Generic_Group" +                       layout="topleft" +                       left="3" +                       bottom="-9" +                       visible="false" +                       width="20" /> +                    </layout_panel> +                    <layout_panel                       name="input_editor_layout_panel">                          <chat_editor                           layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml index 322e34272c..84e0b489d0 100644 --- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml +++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml @@ -6,6 +6,7 @@   layout="topleft"   name="publish_classified"   title="Publishing Classified" + help_topic="profile_edit_classified"   width="320">      <text       top="20" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 2f4da4f9b7..107330d618 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4039,6 +4039,8 @@ Finished download of raw terrain file to:  [DOWNLOAD_PATH].    </notification> +  <!-- RequiredUpdate does not display release notes URL because we don't get +       that from login.cgi's login failure message. -->    <notification     icon="alertmodal.tga"     name="RequiredUpdate" @@ -4056,6 +4058,8 @@ Please download from https://secondlife.com/support/downloads/     name="PauseForUpdate"     type="alertmodal">  Version [VERSION] is required for login. +Release notes: [URL] +  Click OK to download and install.      <tag>confirm</tag>      <usetemplate @@ -4068,6 +4072,8 @@ Click OK to download and install.     name="OptionalUpdateReady"     type="alertmodal">  Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] +  Click OK to install.      <tag>confirm</tag>      <usetemplate @@ -4080,6 +4086,8 @@ Click OK to install.     name="PromptOptionalUpdate"     type="alertmodal">  Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] +  Proceed?      <tag>confirm</tag>      <usetemplate diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml index 4372cf69bf..3be2beb0aa 100644 --- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml @@ -6,45 +6,41 @@   name="conversation_list_item"   mouse_opaque="false"   width="120"> -    <avatar_icon -     follows="top|left" -     height="20" -     default_icon_name="Generic_Person" -     layout="topleft" -     left="9" -     top="2" -     visible="false" -     width="20" /> -    <group_icon -     follows="top|left" -     height="20" -     default_icon_name="Generic_Group" -     layout="topleft" -     left="9" -     top="2" -     visible="false" -     width="20" /> -    <icon -     follows="top|left" -     height="20" -     image_name="Nearby_chat_icon" -     layout="topleft" -     left="10" -     name="nearby_chat_icon" -     top="3" -     visible="false" -     width="20"/> +      <layout_stack       animate="false"       follows="all"       height="24"       layout="topleft" -     left="30" +     left="9"       mouse_opaque="false"       name="conversation_item_stack"       orientation="horizontal"       top="0" -     width="90"> +     width="109"> +      <layout_panel +        auto_resize="false" +        name="session_icon_panel" +        width="24"> +        <avatar_icon +         follows="top|left" +         height="20" +         default_icon_name="Generic_Person" +         layout="topleft" +         left="0" +         top="2" +         visible="false" +         width="20" /> +        <group_icon +         follows="top|left" +         height="20" +         default_icon_name="Generic_Group" +         layout="topleft" +         left="0" +         top="2" +         visible="false" +         width="20" /> +        </layout_panel>          <layout_panel           auto_resize="false"           user_resize="false"         diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 619c869a3d..9fd8366964 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2298,6 +2298,7 @@ For AI Character: Get the closest navigable point to the point provided.  	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</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="MarketplaceNoListing">You have no listings yet.</string>  	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>  	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>  	<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string> @@ -3692,10 +3693,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    Also there are some other places where "generic" is used.    So, let add string with name="generic" with the same value as "generic_request_error" -->    <string name="generic"> -    Error making request, please try again later. +    Please close and reopen the conversation, or relog and try again.    </string>    <string name="generic_request_error"> -    Error making request, please try again later. +    Please close and reopen the conversation, or relog and try again.    </string>    <string name="insufficient_perms_error">      You do not have sufficient permissions. diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 57f2d31eab..f9abc8b25d 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -41,6 +41,7 @@  #include "../test/lltut.h"  #include "llevents.h"  #include "llnotificationsutil.h" +#include "lltrans.h"  #if defined(LL_WINDOWS)  #pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr @@ -77,6 +78,11 @@ void LLViewerWindow::setShowProgress(BOOL show) {}  LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }  LLViewerWindow* gViewerWindow; + +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string) +{ +    return std::string("test_trans"); +}  class LLLogin::Impl  { diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 8eee583a48..547ba5a1fa 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -532,6 +532,9 @@ class WindowsManifest(ViewerManifest):              # For textures              self.path("openjpeg.dll") +            # Uriparser +            self.path("uriparser.dll") +              # These need to be installed as a SxS assembly, currently a 'private' assembly.              # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx              self.path("msvcp140.dll") @@ -1034,6 +1037,7 @@ class DarwinManifest(ViewerManifest):                                  # libnghttp2.major.dylib, which is a symlink to                                  # libnghttp2.version.dylib. Get all of them.                                  "libnghttp2.*dylib", +                                "liburiparser.*dylib",                                  ):                      dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) | 
