diff options
47 files changed, 950 insertions, 660 deletions
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index b46f49ba34..0a83c4a3d7 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -39,6 +39,8 @@ #if !LL_WINDOWS # include <syslog.h> # include <unistd.h> +#else +# include <io.h> #endif // !LL_WINDOWS #include <vector> #include "string.h" @@ -231,14 +233,11 @@ namespace { bool checkANSI(void) { -#if LL_LINUX || LL_DARWIN // Check whether it's okay to use ANSI; if stderr is // a tty then we assume yes. Can be turned off with // the LL_NO_ANSI_COLOR env var. return (0 != isatty(2)) && (NULL == getenv("LL_NO_ANSI_COLOR")); -#endif // LL_LINUX - return FALSE; // works in a cygwin shell... ;) } }; diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 0f76ff23ea..6909a650da 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -567,16 +567,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) // Use the viewer-based thread-safe API which has a // fast/safe check for proxy enable. Would like to // encapsulate this someway... - if (LLProxy::instanceExists()) - { - // Make sure proxy won't be initialized from here, - // it might conflict with LLStartUp::startLLProxy() - LLProxy::getInstance()->applyProxySettings(mCurlHandle); - } - else - { - LL_WARNS() << "Proxy is not initialized!" << LL_ENDL; - } + // Make sure proxy won't be getInstance() from here, + // it is not thread safe + LLProxy::applyProxySettings(mCurlHandle); } else if (gpolicy.mHttpProxy.size()) @@ -817,6 +810,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos)); const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size)); + // FIXME: singleton's instance() is Thread unsafe! Even if stats accumulators inside are. HTTPStats::instance().recordDataUp(read_size); op->mCurlBodyPos += read_size; return read_size; diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 7a0c8cd8f5..aed8943439 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -583,29 +583,39 @@ static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 src // LLImage //--------------------------------------------------------------------------- -LLImage::LLImage(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) +//static +std::string LLImage::sLastErrorMessage; +LLMutex* LLImage::sMutex = NULL; +bool LLImage::sUseNewByteRange = false; +S32 LLImage::sMinimalReverseByteRangePercent = 75; + +//static +void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) { - mMutex = new LLMutex(); - mUseNewByteRange = use_new_byte_range; - mMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent; + sUseNewByteRange = use_new_byte_range; + sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent; + sMutex = new LLMutex(); } -LLImage::~LLImage() +//static +void LLImage::cleanupClass() { - delete mMutex; - mMutex = NULL; + delete sMutex; + sMutex = NULL; } -const std::string& LLImage::getLastErrorMessage() +//static +const std::string& LLImage::getLastError() { static const std::string noerr("No Error"); - return mLastErrorMessage.empty() ? noerr : mLastErrorMessage; + return sLastErrorMessage.empty() ? noerr : sLastErrorMessage; } -void LLImage::setLastErrorMessage(const std::string& message) +//static +void LLImage::setLastError(const std::string& message) { - LLMutexLock m(mMutex); - mLastErrorMessage = message; + LLMutexLock m(sMutex); + sLastErrorMessage = message; } //--------------------------------------------------------------------------- diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 9f8d061293..f66b1666d7 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -30,7 +30,6 @@ #include "lluuid.h" #include "llstring.h" #include "llpointer.h" -#include "llsingleton.h" #include "lltrace.h" const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2 @@ -88,26 +87,25 @@ typedef enum e_image_codec //============================================================================ // library initialization class +// LLImage is frequently used in threads so do not convert it to LLSingleton -class LLImage : public LLParamSingleton<LLImage> +class LLImage { - LLSINGLETON(LLImage, bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75); - ~LLImage(); public: + static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75); + static void cleanupClass(); - const std::string& getLastErrorMessage(); - static const std::string& getLastError() { return getInstance()->getLastErrorMessage(); }; - void setLastErrorMessage(const std::string& message); - static void setLastError(const std::string& message) { getInstance()->setLastErrorMessage(message); } - - bool useNewByteRange() { return mUseNewByteRange; } - S32 getReverseByteRangePercent() { return mMinimalReverseByteRangePercent; } - -private: - LLMutex* mMutex; - std::string mLastErrorMessage; - bool mUseNewByteRange; - S32 mMinimalReverseByteRangePercent; + static const std::string& getLastError(); + static void setLastError(const std::string& message); + + static bool useNewByteRange() { return sUseNewByteRange; } + static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; } + +protected: + static LLMutex* sMutex; + static std::string sLastErrorMessage; + static bool sUseNewByteRange; + static S32 sMinimalReverseByteRangePercent; }; //============================================================================ diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 71cab0554d..4bff21610f 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -281,7 +281,7 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r S32 bytes; S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor); S32 old_bytes = (S32)((F32)(w*h*comp)*rate); - bytes = (LLImage::getInstance()->useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes); + bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes); bytes = llmax(bytes, calcHeaderSizeJ2C()); return bytes; } @@ -322,7 +322,7 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes) { S32 bytes_needed = calcDataSize(discard_level); // Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level - if (bytes >= (bytes_needed*LLImage::getInstance()->getReverseByteRangePercent()/100)) + if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100)) { break; } diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 6a287f0cc5..6ada12962c 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -285,12 +285,27 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& return; } + bool updated_account = true; // assume obsolete value for new arrivals by default + + std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id); + if (it != mCache.end() + && (*it).second.getAccountName() == av_name.getAccountName()) + { + updated_account = false; + } + // Add to the cache mCache[agent_id] = av_name; // Suppress request from the queue mPendingQueue.erase(agent_id); + // notify mute list about changes + if (updated_account && mAccountNameChangedCallback) + { + mAccountNameChangedCallback(agent_id, av_name); + } + // Signal everyone waiting on this name signal_map_t::iterator sig_it = mSignalMap.find(agent_id); if (sig_it != mSignalMap.end()) @@ -303,6 +318,8 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& delete signal; signal = NULL; } + + } void LLAvatarNameCache::requestNamesViaCapability() diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index ba89d569f3..549d1703fa 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -42,6 +42,7 @@ class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache> ~LLAvatarNameCache(); public: typedef boost::signals2::signal<void (void)> use_display_name_signal_t; + typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t; // Import/export the name cache to file. bool importFile(std::istream& istr); @@ -103,6 +104,8 @@ public: void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); + void setAccountNameChangedCallback(const account_name_changed_callback_t& cb) { mAccountNameChangedCallback = cb; } + private: // Handle name response off network. void processName(const LLUUID& agent_id, @@ -141,6 +144,7 @@ private: private: use_display_name_signal_t mUseDisplayNamesSignal; + account_name_changed_callback_t mAccountNameChangedCallback; // Cache starts in a paused state until we can determine if the // current region supports display names. diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 950599217f..d11a1487ab 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -40,6 +40,7 @@ // incoming packet just to do a simple bool test. The getter for this // member is also static bool LLProxy::sUDPProxyEnabled = false; +LLProxy* LLProxy::sProxyInstance = NULL; // Some helpful TCP static functions. static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake @@ -60,11 +61,21 @@ LLProxy::LLProxy(): LLProxy::~LLProxy() { - if (ll_apr_is_initialized()) - { - stopSOCKSProxy(); - disableHTTPProxy(); - } + if (ll_apr_is_initialized()) + { + // locks mutex + stopSOCKSProxy(); + disableHTTPProxy(); + } + // The primary safety of sProxyInstance is the fact that by the + // point SUBSYSTEM_CLEANUP(LLProxy) gets called, nothing should + // be capable of using proxy + sProxyInstance = NULL; +} + +void LLProxy::initSingleton() +{ + sProxyInstance = this; } /** @@ -424,28 +435,28 @@ void LLProxy::cleanupClass() void LLProxy::applyProxySettings(CURL* handle) { // Do a faster unlocked check to see if we are supposed to proxy. - if (mHTTPProxyEnabled) + if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled) { - // We think we should proxy, lock the proxy mutex. - LLMutexLock lock(&mProxyMutex); + // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex + LLMutexLock lock(&sProxyInstance->mProxyMutex); // Now test again to verify that the proxy wasn't disabled between the first check and the lock. - if (mHTTPProxyEnabled) + if (sProxyInstance->mHTTPProxyEnabled) { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()), CURLOPT_PROXYPORT); + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT); - if (mProxyType == LLPROXY_SOCKS) + if (sProxyInstance->mProxyType == LLPROXY_SOCKS) { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); - if (mAuthMethodSelected == METHOD_PASSWORD) + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); + if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD) { - std::string auth_string = mSocksUsername + ":" + mSocksPassword; - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); + std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword; + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); } } else { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); } } } diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 87891901ad..f2eefb26d0 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -225,6 +225,8 @@ class LLProxy: public LLSingleton<LLProxy> LLSINGLETON(LLProxy); LOG_CLASS(LLProxy); + /*virtual*/ void initSingleton(); + public: // Static check for enabled status for UDP packets. Call from main thread only. static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } @@ -250,7 +252,7 @@ public: // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false. // Safe to call from any thread. - void applyProxySettings(CURL* handle); + static void applyProxySettings(CURL* handle); // Start a connection to the SOCKS 5 proxy. Call from main thread only. S32 startSOCKSProxy(LLHost host); @@ -343,6 +345,10 @@ private: /*########################################################################################### END OF SHARED MEMBERS ###########################################################################################*/ + + // A hack to get arround getInstance() and capture_dependency() which are unsafe to use inside threads + // set/reset on init/cleanup, strictly for use in applyProxySettings + static LLProxy* sProxyInstance; }; #endif diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index 70ab006fd6..8c01784071 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -32,6 +32,7 @@ #include "llpointer.h" // LLPointer<> #include "llrect.h" +#include "llsingleton.h" #include "llglslshader.h" class LLColor4; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 333d03f208..ac86101f69 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -1475,4 +1475,43 @@ void LLUrlEntryExperienceProfile::onExperienceDetails( const LLSD& experience_de callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null); } +// +// LLUrlEntryEmail Describes an IPv6 address +// +LLUrlEntryIPv6::LLUrlEntryIPv6() + : LLUrlEntryBase() +{ + mHostPath = "https?://\\[([a-f0-9:]+:+)+[a-f0-9]+]"; + mPattern = boost::regex(mHostPath + "(:\\d{1,5})?(/\\S*)?", + boost::regex::perl | boost::regex::icase); + mMenuName = "menu_url_http.xml"; + mTooltip = LLTrans::getString("TooltipHttpUrl"); +} +std::string LLUrlEntryIPv6::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase); + boost::match_results<std::string::const_iterator> matches; + + if (boost::regex_search(url, matches, regex)) + { + return url.substr(0, matches[0].length()); + } + else + { + return url; + } +} + +std::string LLUrlEntryIPv6::getQuery(const std::string &url) const +{ + boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase); + boost::match_results<std::string::const_iterator> matches; + + return boost::regex_replace(url, regex, ""); +} + +std::string LLUrlEntryIPv6::getUrl(const std::string &string) const +{ + return string; +} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 78c149d9fd..0a0c247a6a 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -513,5 +513,18 @@ public: /*virtual*/ std::string getUrl(const std::string &string) const; }; +/// +/// LLUrlEntryEmail Describes an IPv6 address +/// +class LLUrlEntryIPv6 : public LLUrlEntryBase +{ +public: + LLUrlEntryIPv6(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getUrl(const std::string &string) const; + /*virtual*/ std::string getQuery(const std::string &url) const; + + std::string mHostPath; +}; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index ba6fa1e2e9..321a0ec5b9 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -79,6 +79,7 @@ LLUrlRegistry::LLUrlRegistry() mUrlEntrySLLabel = new LLUrlEntrySLLabel(); registerUrl(mUrlEntrySLLabel); registerUrl(new LLUrlEntryEmail()); + registerUrl(new LLUrlEntryIPv6()); } LLUrlRegistry::~LLUrlRegistry() diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 3c34fd269e..4a4fdb72e3 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -903,4 +903,38 @@ namespace tut "and even no www something lindenlab.com", ""); } + + template<> template<> + void object::test<16>() + { + // + // test LLUrlEntryIPv6 + // + LLUrlEntryIPv6 url; + + // Regex tests. + testRegex("match urls with a protocol", url, + "this url should match http://[::1]", + "http://[::1]"); + + testRegex("match urls with a protocol and query", url, + "this url should match http://[::1]/file.mp3", + "http://[::1]/file.mp3"); + + testRegex("match urls with a protocol", url, + "this url should match http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]", + "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]"); + + testRegex("match urls with port", url, + "let's specify some port http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080", + "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080"); + + testRegex("don't match urls w/o protocol", url, + "looks like an url something [2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d] but no https prefix", + ""); + + testRegex("don't match incorrect urls", url, + "http://[ 2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d ]", + ""); + } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7c0124322c..9382a367f7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2073,6 +2073,7 @@ bool LLAppViewer::cleanup() LLUIImageList::getInstance()->cleanUp(); // This should eventually be done in LLAppViewer + SUBSYSTEM_CLEANUP(LLImage); SUBSYSTEM_CLEANUP(LLVFSThread); SUBSYSTEM_CLEANUP(LLLFSThread); @@ -2116,6 +2117,7 @@ bool LLAppViewer::cleanup() LLWeb::loadURLExternal( gLaunchFileOnQuit, false ); LL_INFOS() << "File launched." << LL_ENDL; } + // make sure nothing uses applyProxySettings by this point. LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL; SUBSYSTEM_CLEANUP(LLProxy); LLCore::LLHttp::cleanup(); @@ -2181,7 +2183,7 @@ bool LLAppViewer::initThreads() { static const bool enable_threads = true; - LLImage::initParamSingleton(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); + LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); LLVFSThread::initClass(enable_threads && false); LLLFSThread::initClass(enable_threads && false); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d208e135bb..f0aa355342 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -500,68 +500,74 @@ void LLAppViewerWin32::disableWinErrorReporting() } const S32 MAX_CONSOLE_LINES = 500; +// Only defined in newer SDKs than we currently use +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4 +#endif -static bool create_console() -{ - int h_con_handle; - long l_std_handle; +namespace { - CONSOLE_SCREEN_BUFFER_INFO coninfo; - FILE *fp; +FILE* set_stream(const char* which, DWORD handle_id, const char* mode); +bool create_console() +{ // allocate a console for this app const bool isConsoleAllocated = AllocConsole(); // set the screen buffer to be big enough to let us scroll text + CONSOLE_SCREEN_BUFFER_INFO coninfo; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); coninfo.dwSize.Y = MAX_CONSOLE_LINES; SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); // redirect unbuffered STDOUT to the console - l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE); - h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); - if (h_con_handle == -1) + FILE* fp = set_stream("stdout", STD_OUTPUT_HANDLE, "w"); + if (fp) { - LL_WARNS() << "create_console() failed to open stdout handle" << LL_ENDL; - } - else - { - fp = _fdopen( h_con_handle, "w" ); *stdout = *fp; - setvbuf( stdout, NULL, _IONBF, 0 ); } // redirect unbuffered STDIN to the console - l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE); - h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); - if (h_con_handle == -1) + fp = set_stream("stdin", STD_INPUT_HANDLE, "r"); + if (fp) { - LL_WARNS() << "create_console() failed to open stdin handle" << LL_ENDL; - } - else - { - fp = _fdopen( h_con_handle, "r" ); *stdin = *fp; - setvbuf( stdin, NULL, _IONBF, 0 ); } // redirect unbuffered STDERR to the console - l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE); - h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); + fp = set_stream("stderr", STD_ERROR_HANDLE, "w"); + if (fp) + { + *stderr = *fp; + } + + return isConsoleAllocated; +} + +FILE* set_stream(const char* desc, DWORD handle_id, const char* mode) +{ + auto l_std_handle = GetStdHandle(handle_id); + int h_con_handle = _open_osfhandle(reinterpret_cast<intptr_t>(l_std_handle), _O_TEXT); if (h_con_handle == -1) { - LL_WARNS() << "create_console() failed to open stderr handle" << LL_ENDL; + LL_WARNS() << "create_console() failed to open " << desc << " handle" << LL_ENDL; + return nullptr; } else { - fp = _fdopen( h_con_handle, "w" ); - *stderr = *fp; - setvbuf( stderr, NULL, _IONBF, 0 ); + FILE* fp = _fdopen( h_con_handle, mode ); + setvbuf( fp, NULL, _IONBF, 0 ); + // Enable color processing on Windows 10 console windows. + DWORD dwMode = 0; + GetConsoleMode(l_std_handle, &dwMode); + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(l_std_handle, dwMode); + return fp; } - - return isConsoleAllocated; } +} // anonymous namespace + LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) : mCmdLine(cmd_line), mIsConsoleAllocated(false) diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 3ab8fed2c6..127055459d 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -129,23 +129,14 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item) switch(item->getType()) { case LLAssetType::AT_OBJECT: - if (get_is_item_worn(item->getUUID())) - { - acceptable = false; - } - break; case LLAssetType::AT_BODYPART: case LLAssetType::AT_CLOTHING: { - BOOL copyable = false; - if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true; - - if (!copyable && get_is_item_worn(item->getUUID())) + if (get_is_item_worn(item->getUUID())) { - // worn no-copy items can't be transfered, - // but it is valid to transfer a copy of a worn item acceptable = false; } + break; } break; default: diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index dbf7639539..3ef7b749a6 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -944,9 +944,13 @@ static void formatDateString(std::string &date_string) } } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members"); + // static void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1050,9 +1054,13 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties"); + //static void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; if (!msg) { @@ -1122,9 +1130,12 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data"); // static void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1207,9 +1218,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members"); // static void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 657c65c68d..b1de884f06 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -7655,8 +7655,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids) for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it) { LLViewerInventoryItem* item = gInventory.getItem(*it); - LLAssetType::EType asset_type = item->getType(); - if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE)) + if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE)) { return false; } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 646d92b9e1..0083ab0397 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2397,16 +2397,19 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { bool open_multi_preview = true; - for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) + if ("open" == action) { - LLFolderViewItem* folder_item = *set_iter; - if (folder_item) + for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) { - LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem()); - if (!bridge || !bridge->isMultiPreviewAllowed()) + LLFolderViewItem* folder_item = *set_iter; + if (folder_item) { - open_multi_preview = false; - break; + LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem()); + if (!bridge || !bridge->isMultiPreviewAllowed()) + { + open_multi_preview = false; + break; + } } } } diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 64df449c26..8a10a38b37 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -169,6 +169,14 @@ LLMuteList::LLMuteList() : gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1, _PREHASH_UseCachedMuteList, processUseCachedMuteList, static_cast<void**>(NULL))); + + // make sure mute list's instance gets initialized before we start any name requests + LLAvatarNameCache::getInstance()->setAccountNameChangedCallback([this](const LLUUID& id, const LLAvatarName& av_name) + { + // it would be better to just pass LLAvatarName instead of doing unnesssesary copies + // but this way is just more convinient + onAccountNameChanged(id, av_name.getUserName()); + }); } //----------------------------------------------------------------------------- @@ -179,6 +187,11 @@ LLMuteList::~LLMuteList() } +void LLMuteList::cleanupSingleton() +{ + LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL); +} + BOOL LLMuteList::isLinden(const std::string& name) const { std::string username = boost::replace_all_copy(name, ".", " "); @@ -232,8 +245,8 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) LL_WARNS() << "Trying to self; ignored" << LL_ENDL; return FALSE; } - - S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit"); + + static LLCachedControl<S32> mute_list_limit(gSavedSettings, "MuteListLimit", 1000); if (getMutes().size() >= mute_list_limit) { LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL; @@ -358,6 +371,10 @@ void LLMuteList::updateAdd(const LLMute& mute) msg->addU32("MuteFlags", mute.mFlags); gAgent.sendReliableMessage(); + if (!mIsLoaded) + { + LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL; + } mIsLoaded = TRUE; // why is this here? -MG } @@ -412,7 +429,6 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags) // Must be after erase. notifyObserversDetailed(localmute); - setLoaded(); // why is this here? -MG } else { @@ -426,7 +442,6 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags) mLegacyMutes.erase(legacy_it); // Must be after erase. notifyObserversDetailed(mute); - setLoaded(); // why is this here? -MG } } @@ -584,6 +599,19 @@ BOOL LLMuteList::loadFromFile(const std::string& filename) } fclose(fp); setLoaded(); + + // server does not maintain up-to date account names (not display names!) + // in this list, so it falls to viewer. + pending_names_t::iterator iter = mPendingAgentNameUpdates.begin(); + pending_names_t::iterator end = mPendingAgentNameUpdates.end(); + while (iter != end) + { + // this will send updates to server, make sure mIsLoaded is set + onAccountNameChanged(iter->first, iter->second); + iter++; + } + mPendingAgentNameUpdates.clear(); + return TRUE; } @@ -767,6 +795,48 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_ delete local_filename_and_path; } +void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username) +{ + if (mIsLoaded) + { + LLMute mute(id, username, LLMute::AGENT); + mute_set_t::iterator mute_it = mMutes.find(mute); + if (mute_it != mMutes.end() + && mute_it->mName != mute.mName + && mute_it->mType == LLMute::AGENT) // just in case, it is std::set, not map + { + // existing mute, but name changed, copy data + mute.mFlags = mute_it->mFlags; + + // erase old variant + mMutes.erase(mute_it); + + // (re)add the mute entry. + { + std::pair<mute_set_t::iterator, bool> result = mMutes.insert(mute); + if (result.second) + { + LL_INFOS() << "Muting " << mute.mName << " id " << mute.mID << " flags " << mute.mFlags << LL_ENDL; + updateAdd(mute); + // Do not notify observers here, observers do not know or need to handle name changes + // Example: block list considers notifyObserversDetailed as a selection update; + // Various chat/voice statuses care only about id and flags + // Since apropriate update time for account names is considered to be in 'hours' it is + // fine not to update UI (will be fine after restart or couple other changes) + + } + } + } + } + else + { + // Delay update until we load file + // Ex: Buddies list can arrive too early since we prerequest + // names from Buddies list before we load blocklist + mPendingAgentNameUpdates[id] = username; + } +} + void LLMuteList::addObserver(LLMuteListObserver* observer) { mObservers.insert(observer); diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index f2fcf3dbb3..0d426fbd48 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -73,6 +73,7 @@ class LLMuteList : public LLSingleton<LLMuteList> { LLSINGLETON(LLMuteList); ~LLMuteList(); + /*virtual*/ void cleanupSingleton(); public: // reasons for auto-unmuting a resident enum EAutoReason @@ -131,6 +132,7 @@ private: static void processUseCachedMuteList(LLMessageSystem* msg, void**); static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status); + void onAccountNameChanged(const LLUUID& id, const std::string& username); private: struct compare_by_name @@ -155,7 +157,9 @@ private: }; typedef std::set<LLMute, compare_by_id> mute_set_t; mute_set_t mMutes; - + typedef std::map<LLUUID, std::string> pending_names_t; + pending_names_t mPendingAgentNameUpdates; + typedef std::set<std::string> string_set_t; string_set_t mLegacyMutes; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 3bae0cebfb..116b23e595 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -54,6 +54,7 @@ #include "lltrans.h" #include "llviewerassettype.h" #include "llviewerinventory.h" +#include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerregion.h" #include "llviewerwindow.h" @@ -82,6 +83,7 @@ BOOL LLPanelContents::postBuild() childSetAction("button new script",&LLPanelContents::onClickNewScript, this); childSetAction("button permissions",&LLPanelContents::onClickPermissions, this); + childSetAction("btn_reset_scripts", &LLPanelContents::onClickResetScripts, this); mPanelInventoryObject = getChild<LLPanelObjectInventory>("contents_inventory"); @@ -106,6 +108,7 @@ void LLPanelContents::getState(LLViewerObject *objectp ) if( !objectp ) { getChildView("button new script")->setEnabled(FALSE); + getChildView("btn_reset_scripts")->setEnabled(FALSE); return; } @@ -125,6 +128,8 @@ void LLPanelContents::getState(LLViewerObject *objectp ) ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))); + getChildView("btn_reset_scripts")->setEnabled(editable); + getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced()); mPanelInventoryObject->setEnabled(!objectp->isPermanentEnforced()); } @@ -206,3 +211,9 @@ void LLPanelContents::onClickPermissions(void *userdata) LLPanelContents* self = (LLPanelContents*)userdata; gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterReg::showInstance("bulk_perms")); } + +// static +void LLPanelContents::onClickResetScripts(void *userdata) +{ + handle_selected_script_action("reset"); +} diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index 6ecc78afa0..5b1a57de42 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -53,6 +53,7 @@ public: static void onClickNewScript(void*); static void onClickPermissions(void*); + static void onClickResetScripts(void*); // Key suffix for "tentative" fields static const char* TENTATIVE_SUFFIX; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 1d87aa6f5d..dd1130aeba 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -1282,6 +1282,7 @@ void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type //e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE applyListViewFilter(static_cast<EListViewItemType>(LVIT_SHAPE + type)); + mWearableItemsList->setMenuWearableType(type); } static void update_status_widget_rect(LLView * widget, S32 right_border) diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 9d8be4b2fe..1e91da529c 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -401,7 +401,7 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success, { const U32 ext_length = 3; std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length); - + LLStringUtil::toLower(extension); // We only support saving in PNG or TGA format LLPointer<LLImageFormatted> image; if(extension == "png") diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index d53cc3f745..bc07821ccd 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -316,24 +316,25 @@ bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LL bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload) { bool succ = false; - - codec = LLImageBase::getCodecFromExtension(exten); + std::string exten_lc(exten); + LLStringUtil::toLower(exten_lc); + codec = LLImageBase::getCodecFromExtension(exten_lc); if (codec != IMG_CODEC_INVALID) { asset_type = LLAssetType::AT_TEXTURE; succ = true; } - else if (exten == "wav") + else if (exten_lc == "wav") { asset_type = LLAssetType::AT_SOUND; succ = true; } - else if (exten == "anim") + else if (exten_lc == "anim") { asset_type = LLAssetType::AT_ANIMATION; succ = true; } - else if (!bulk_upload && (exten == "bvh")) + else if (!bulk_upload && (exten_lc == "bvh")) { asset_type = LLAssetType::AT_ANIMATION; succ = true; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b6c7be2ed3..df8cf6bf81 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -690,19 +690,6 @@ class LLAdvancedCheckHUDInfo : public view_listener_t }; -////////////// -// FLYING // -////////////// - -class LLAdvancedAgentFlyingInfo : public view_listener_t -{ - bool handleEvent(const LLSD&) - { - return gAgent.getFlying(); - } -}; - - /////////////////////// // CLEAR GROUP CACHE // /////////////////////// @@ -3702,6 +3689,35 @@ bool enable_sitdown_self() return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying(); } +class LLSelfToggleSitStand : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + if (isAgentAvatarValid()) + { + if (gAgentAvatarp->isSitting()) + { + gAgent.standUp(); + } + else + { + gAgent.sitDown(); + } + } + return true; + } +}; + +bool enable_sit_stand() +{ + return enable_sitdown_self() || enable_standup_self(); +} + +bool enable_fly_land() +{ + return gAgent.getFlying() || LLAgent::enableFlying(); +} + class LLCheckPanelPeopleTab : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -4104,7 +4120,7 @@ void handle_reset_view() // switching to outfit selector should automagically save any currently edited wearable LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); } - + gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE); reset_view_final( TRUE ); LLFloaterCamera::resetCameraMode(); } @@ -7202,58 +7218,62 @@ class LLToolsSelectedScriptAction : public view_listener_t { bool handleEvent(const LLSD& userdata) { - std::string action = userdata.asString(); - bool mono = false; - std::string msg, name; - std::string title; - if (action == "compile mono") - { - name = "compile_queue"; - mono = true; - msg = "Recompile"; - title = LLTrans::getString("CompileQueueTitle"); - } - if (action == "compile lsl") - { - name = "compile_queue"; - msg = "Recompile"; - title = LLTrans::getString("CompileQueueTitle"); - } - else if (action == "reset") - { - name = "reset_queue"; - msg = "Reset"; - title = LLTrans::getString("ResetQueueTitle"); - } - else if (action == "start") - { - name = "start_queue"; - msg = "SetRunning"; - title = LLTrans::getString("RunQueueTitle"); - } - else if (action == "stop") - { - name = "stop_queue"; - msg = "SetRunningNot"; - title = LLTrans::getString("NotRunQueueTitle"); - } - LLUUID id; id.generate(); - - LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id)); - if (queue) - { - queue->setMono(mono); - queue_actions(queue, msg); - queue->setTitle(title); - } - else - { - LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL; - } + handle_selected_script_action(userdata.asString()); return true; } }; +void handle_selected_script_action(const std::string& action) +{ + bool mono = false; + std::string msg, name; + std::string title; + if (action == "compile mono") + { + name = "compile_queue"; + mono = true; + msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); + } + if (action == "compile lsl") + { + name = "compile_queue"; + msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); + } + else if (action == "reset") + { + name = "reset_queue"; + msg = "Reset"; + title = LLTrans::getString("ResetQueueTitle"); + } + else if (action == "start") + { + name = "start_queue"; + msg = "SetRunning"; + title = LLTrans::getString("RunQueueTitle"); + } + else if (action == "stop") + { + name = "stop_queue"; + msg = "SetRunningNot"; + title = LLTrans::getString("NotRunQueueTitle"); + } + LLUUID id; id.generate(); + + LLFloaterScriptQueue* queue = LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id)); + if (queue) + { + queue->setMono(mono); + queue_actions(queue, msg); + queue->setTitle(title); + } + else + { + LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL; + } +} + void handle_selected_texture_info(void*) { for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); @@ -8884,7 +8904,7 @@ void initialize_menus() // Agent commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); - enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); + enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land)); commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); @@ -8932,9 +8952,6 @@ void initialize_menus() view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - // Me > Movement - view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); - //Communicate Nearby chat view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat"); @@ -9198,11 +9215,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); // Self context menu - view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp"); - enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self)); - view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown"); - enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self)); - enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self)); + view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand"); + enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand)); view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments"); view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 6882405407..74a15af50c 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -110,6 +110,8 @@ void handle_object_return(); void handle_object_delete(); void handle_object_edit(); +void handle_selected_script_action(const std::string& action); + void handle_buy_land(); // Takes avatar UUID, or if no UUID passed, uses last selected object diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index d1d3a7fc12..7603a6b18c 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -683,7 +683,8 @@ class LLFileTakeSnapshotToDisk : public view_listener_t S32 width = gViewerWindow->getWindowWidthRaw(); S32 height = gViewerWindow->getWindowHeightRaw(); - if (gSavedSettings.getBOOL("HighResSnapshot")) + BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot"); + if (high_res) { width *= 2; height *= 2; @@ -695,7 +696,9 @@ class LLFileTakeSnapshotToDisk : public view_listener_t TRUE, FALSE, gSavedSettings.getBOOL("RenderUIInSnapshot"), - FALSE)) + FALSE, + LLSnapshotModel::SNAPSHOT_TYPE_COLOR, + high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side { LLPointer<LLImageFormatted> formatted; LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e077626461..e1c44d6be8 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2220,8 +2220,12 @@ protected: } }; +static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM"); + void process_improved_im(LLMessageSystem *msg, void **user_data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM); + LLUUID from_id; BOOL from_group; LLUUID to_id; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 44c1fbd066..299d82d3b2 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -137,7 +137,7 @@ private: }; -static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 6 * 1024; // max snapshot image size 6144 * 6144 +static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 * 7680 UHDTV2 class LLViewerWindow : public LLWindowCallbacks { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2ffd462ac3..34b801a097 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2319,7 +2319,8 @@ bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture) //setup new materials for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) { - LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second); + // These are placeholder materials, they shouldn't be sent to server + LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second); LLViewerObject::setTEMaterialParams(it->first, it->second); } diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index e7bbee5efd..3d1bc5249d 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -639,6 +639,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) : LLInventoryItemsList(p) { setSortOrder(E_SORT_BY_TYPE_LAYER, false); + mMenuWearableType = LLWearableType::WT_NONE; mIsStandalone = p.standalone; if (mIsStandalone) { @@ -730,10 +731,15 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y) getSelectedUUIDs(selected_uuids); if (selected_uuids.empty()) { - return; + if ((mMenuWearableType != LLWearableType::WT_NONE) && (size() == 0)) + { + ContextMenu::instance().show(this, mMenuWearableType, x, y); + } + } + else + { + ContextMenu::instance().show(this, selected_uuids, x, y); } - - ContextMenu::instance().show(this, selected_uuids, x, y); } void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now) @@ -784,6 +790,46 @@ void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, const uuid_ve mParent = NULL; // to avoid dereferencing an invalid pointer } +void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y) +{ + mParent = dynamic_cast<LLWearableItemsList*>(spawning_view); + LLContextMenu* menup = mMenuHandle.get(); + if (menup) + { + //preventing parent (menu holder) from deleting already "dead" context menus on exit + LLView* parent = menup->getParent(); + if (parent) + { + parent->removeChild(menup); + } + delete menup; + mUUIDs.clear(); + } + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("Wearable.CreateNew", boost::bind(createNewWearableByType, w_type)); + menup = createFromFile("menu_wearable_list_item.xml"); + if (!menup) + { + LL_WARNS() << "Context menu creation failed" << LL_ENDL; + return; + } + setMenuItemVisible(menup, "create_new", true); + setMenuItemEnabled(menup, "create_new", true); + setMenuItemVisible(menup, "wearable_attach_to", false); + setMenuItemVisible(menup, "wearable_attach_to_hud", false); + + std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type)); + LLMenuItemGL* menu_item = menup->getChild<LLMenuItemGL>("create_new"); + menu_item->setLabel(new_label); + + mMenuHandle = menup->getHandle(); + menup->show(x, y); + LLMenuGL::showPopup(spawning_view, menup, x, y); + + mParent = NULL; // to avoid dereferencing an invalid pointer +} + // virtual LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() { @@ -1004,4 +1050,10 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id) LLAgentWearables::createWearable(item->getWearableType(), true); } +// static +void LLWearableItemsList::ContextMenu::createNewWearableByType(LLWearableType::EType type) +{ + LLAgentWearables::createWearable(type, true); +} + // EOF diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index f3182ed163..ba8488b237 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -415,6 +415,8 @@ public: public: /*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y); + void show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y); + protected: enum { MASK_CLOTHING = 0x01, @@ -431,6 +433,7 @@ public: static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val); static void updateMask(U32& mask, LLAssetType::EType at); static void createNewWearable(const LLUUID& item_id); + static void createNewWearableByType(LLWearableType::EType type); LLWearableItemsList* mParent; }; @@ -469,6 +472,8 @@ public: void setSortOrder(ESortOrder sort_order, bool sort_now = true); + void setMenuWearableType(LLWearableType::EType type) { mMenuWearableType = type; } + protected: friend class LLUICtrlFactory; LLWearableItemsList(const LLWearableItemsList::Params& p); @@ -479,6 +484,8 @@ protected: bool mWornIndicationEnabled; ESortOrder mSortOrder; + + LLWearableType::EType mMenuWearableType; }; #endif //LL_LLWEARABLEITEMSLIST_H diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml index 92c5d8bcbe..3df2683ca8 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar.xml @@ -14,7 +14,7 @@ help_topic="avatar" save_rect="true" save_visibility="true" - title="CHOOSE AN AVATAR" + title="COMPLETE AVATARS" width="700"> <web_browser top="25" diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml index fdea7a821a..35ad87ceb0 100644 --- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml +++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml @@ -11,7 +11,7 @@ save_rect="true" single_instance="true" reuse_instance="true" - title="APPEARANCE" + title="AVATAR" min_height="440" min_width="333" width="333"> diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml index 3b0b6723c7..ee6defce9d 100644 --- a/indra/newview/skins/default/xui/en/floater_my_scripts.xml +++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml @@ -7,7 +7,7 @@ layout="topleft" name="myscripts" save_rect="true" - title="My Scripts" + title="ATTACHMENT SCRIPTS" min_width="620" width="620"> <panel diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 0abee2ff80..1377bad6cf 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2575,13 +2575,22 @@ even though the user gets a free copy. border_visible="true" bevel_style="in" follows="left|top|right" - height="325" + height="300" layout="topleft" left="10" name="contents_inventory" top="50" width="275" /> - </panel> + <button + follows="left|bottom" + height="23" + label="Reset Scripts" + layout="topleft" + left="10" + name="btn_reset_scripts" + bottom="-1" + width="118" /> + </panel> </tab_container> <panel follows="left|top" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 38f4b7715f..7ad692038e 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -173,16 +173,13 @@ parameter="avatar_render_settings" /> </menu_item_call> </context_menu> - <menu_item_separator - layout="topleft" name="Impostor seperator"/> - <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 59faf6a9f5..03c05e6591 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -4,7 +4,7 @@ name="Attachment Pie"> <menu_item_call enabled="false" - label="Touch" + label="Touch item" layout="topleft" name="Attachment Object Touch"> <menu_item_call.on_click @@ -13,19 +13,9 @@ function="Object.EnableTouch" name="EnableTouch"/> </menu_item_call> - <!--menu_item_call - label="Stand Up" - layout="topleft" - name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call--> <menu_item_call enabled="false" - label="Edit" + label="Edit item" layout="topleft" name="Edit..."> <menu_item_call.on_click @@ -35,7 +25,7 @@ </menu_item_call> <menu_item_call enabled="false" - label="Detach" + label="Detach item" layout="topleft" name="Detach"> <menu_item_call.on_click @@ -46,36 +36,15 @@ <menu_item_separator layout="topleft" /> - <menu_item_call - label="Sit Down" - layout="topleft" - name="Sit Down Here"> - <menu_item_call.on_click - function="Self.SitDown" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableSitDown" /> - </menu_item_call> - - <menu_item_call -label="Stand Up" -layout="topleft" -name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> <menu_item_call - label="My Appearance" + label="Outfits..." name="Change Outfit"> <menu_item_call.on_click function="CustomizeAvatar" /> <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Outfit" + <menu_item_call label="Edit current outfit..." layout="topleft" name="Edit Outfit"> <menu_item_call.on_click @@ -83,7 +52,7 @@ name="Edit Outfit"> <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Shape" + <menu_item_call label="Shape..." layout="topleft" name="Edit My Shape"> <menu_item_call.on_click @@ -91,7 +60,7 @@ name="Edit Outfit"> <menu_item_call.on_enable function="Edit.EnableEditShape" /> </menu_item_call> - <menu_item_call label="Hover Height" + <menu_item_call label="Hover height..." layout="topleft" name="Hover Height"> <menu_item_call.on_click @@ -99,42 +68,42 @@ name="Edit Outfit"> <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> - <menu_item_call label="Reset Skeleton" - layout="topleft" - name="Reset Skeleton"> - <menu_item_call.on_click - function="Avatar.ResetSkeleton" /> - </menu_item_call> - <menu_item_call label="Reset Skeleton And Animations" - layout="topleft" - name="Reset Skeleton And Animations"> - <menu_item_call.on_click - function="Avatar.ResetSkeletonAndAnimations" /> - </menu_item_call> - + <menu_item_separator/> <menu_item_call - label="My Friends" + label="Sit / stand" layout="topleft" - name="Friends..."> + name="Sit stand"> <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> </menu_item_call> <menu_item_call - label="My Groups" - layout="topleft" - name="Groups..."> + label="Fly / land" + name="Fly land"> <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> </menu_item_call> <menu_item_call - label="My Profile" - layout="topleft" - name="Profile..."> + label="Stop animations" + name="Stop Animating My Avatar"> <menu_item_call.on_click - function="ShowAgentProfile" - parameter="agent" /> + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="Reset skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset skeleton and animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> </menu_item_call> <menu_item_call label="Debug Textures" @@ -152,27 +121,13 @@ name="Edit Outfit"> <menu_item_call.on_visible function="Advanced.EnableAppearanceToXML"/> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - enabled="false" - label="Drop" - layout="topleft" - name="Drop"> - <menu_item_call.on_click - function="Attachment.Drop" /> - <menu_item_call.on_enable - function="Attachment.EnableDrop" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index f9fb847910..acbb9b860d 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -165,16 +165,13 @@ </menu_item_call> </context_menu> - <menu_item_separator - layout="topleft" name="Impostor seperator"/> - <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 9e181d0b6d..3dcafb13ef 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -3,209 +3,7 @@ layout="topleft" name="Self Pie"> <menu_item_call - label="Sit Down" - layout="topleft" - name="Sit Down Here"> - <menu_item_call.on_click - function="Self.SitDown" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableSitDown" /> - </menu_item_call> - <menu_item_call - label="Stand Up" - layout="topleft" - name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> - <context_menu - label="Take Off" - layout="topleft" - name="Take Off >"> - <context_menu - label="Clothes" - layout="topleft" - name="Clothes >"> - <menu_item_call - enabled="false" - label="Shirt" - layout="topleft" - name="Shirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Pants" - layout="topleft" - name="Pants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="pants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="pants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Skirt" - layout="topleft" - name="Skirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="skirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="skirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Shoes" - layout="topleft" - name="Shoes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shoes" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shoes" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Socks" - layout="topleft" - name="Socks"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="socks" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="socks" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Jacket" - layout="topleft" - name="Jacket"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="jacket" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="jacket" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Gloves" - layout="topleft" - name="Gloves"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="gloves" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="gloves" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Undershirt" - layout="topleft" - name="Self Undershirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="undershirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="undershirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Underpants" - layout="topleft" - name="Self Underpants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="underpants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="underpants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Tattoo" - layout="topleft" - name="Self Tattoo"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="tattoo" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="tattoo" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Physics" - layout="topleft" - name="Self Physics"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="physics" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="physics" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Alpha" - layout="topleft" - name="Self Alpha"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="alpha" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="alpha" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="All Clothes" - layout="topleft" - name="All Clothes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="all" /> - </menu_item_call> - </context_menu> - <context_menu - label="HUD" - layout="topleft" - name="Object Detach HUD" /> - <context_menu - label="Detach" - layout="topleft" - name="Object Detach" /> - <menu_item_call - label="Detach All" - layout="topleft" - name="Detach All"> - <menu_item_call.on_click - function="Self.RemoveAllAttachments" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableRemoveAllAttachments" /> - </menu_item_call> - </context_menu> - <menu_item_call - label="My Appearance" + label="Outfits..." layout="topleft" name="Chenge Outfit"> <menu_item_call.on_click @@ -213,7 +11,7 @@ <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Outfit" + <menu_item_call label="Edit current outfit..." layout="topleft" name="Edit Outfit"> <menu_item_call.on_click @@ -221,7 +19,7 @@ <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Shape" + <menu_item_call label="Shape..." layout="topleft" name="Edit My Shape"> <menu_item_call.on_click @@ -229,7 +27,7 @@ <menu_item_call.on_enable function="Edit.EnableEditShape" /> </menu_item_call> - <menu_item_call label="Hover Height" + <menu_item_call label="Hover height..." layout="topleft" name="Hover Height"> <menu_item_call.on_click @@ -237,42 +35,225 @@ <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> - <menu_item_call label="Reset Skeleton" + <context_menu + label="Take Off" + layout="topleft" + name="Take Off >"> + <context_menu + label="Clothes" + layout="topleft" + name="Clothes >"> + <menu_item_call + enabled="false" + label="Shirt" + layout="topleft" + name="Shirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pants" + layout="topleft" + name="Pants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="pants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="pants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Skirt" + layout="topleft" + name="Skirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="skirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Shoes" + layout="topleft" + name="Shoes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shoes" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Socks" + layout="topleft" + name="Socks"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="socks" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="socks" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Jacket" + layout="topleft" + name="Jacket"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="jacket" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Gloves" + layout="topleft" + name="Gloves"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="gloves" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Undershirt" + layout="topleft" + name="Self Undershirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="undershirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Underpants" + layout="topleft" + name="Self Underpants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="underpants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Tattoo" + layout="topleft" + name="Self Tattoo"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="tattoo" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="tattoo" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Physics" + layout="topleft" + name="Self Physics"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="physics" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="physics" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Alpha" + layout="topleft" + name="Self Alpha"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="alpha" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="alpha" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="All Clothes" + layout="topleft" + name="All Clothes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="all" /> + </menu_item_call> + </context_menu> + <context_menu + label="HUD" + layout="topleft" + name="Object Detach HUD" /> + <context_menu + label="Detach" + layout="topleft" + name="Object Detach" /> + <menu_item_call + label="Detach All" + layout="topleft" + name="Detach All"> + <menu_item_call.on_click + function="Self.RemoveAllAttachments" + parameter="" /> + <menu_item_call.on_enable + function="Self.EnableRemoveAllAttachments" /> + </menu_item_call> + </context_menu> + <menu_item_separator/> + <menu_item_call + label="Sit / stand" + layout="topleft" + name="Sit stand"> + <menu_item_call.on_click + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> + </menu_item_call> + <menu_item_call + label="Fly / land" + name="Fly land"> + <menu_item_call.on_click + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> + </menu_item_call> + <menu_item_call + label="Stop animations" + name="Stop Animating My Avatar"> + <menu_item_call.on_click + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="Reset skeleton" layout="topleft" name="Reset Skeleton"> <menu_item_call.on_click function="Avatar.ResetSkeleton" /> - </menu_item_call> - <menu_item_call label="Reset Skeleton And Animations" + </menu_item_call> + <menu_item_call label="Reset skeleton and animations" layout="topleft" name="Reset Skeleton And Animations"> <menu_item_call.on_click function="Avatar.ResetSkeletonAndAnimations" /> </menu_item_call> - <menu_item_call - label="My Friends" - layout="topleft" - name="Friends..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> - </menu_item_call> - <menu_item_call - label="My Groups" - layout="topleft" - name="Groups..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> - </menu_item_call> - <menu_item_call - label="My Profile" - layout="topleft" - name="Profile..."> - <menu_item_call.on_click - function="ShowAgentProfile" - parameter="agent" /> - </menu_item_call> <menu_item_call label="Debug Textures" name="Debug..."> @@ -289,8 +270,6 @@ <menu_item_call.on_visible function="Advanced.EnableAppearanceToXML"/> </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call enabled="false" label="Block Particle Owner" @@ -298,7 +277,7 @@ <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 873b95926b..d81ad1c48b 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -15,24 +15,6 @@ function="ShowAgentProfile" parameter="agent" /> </menu_item_call> - <menu_item_call - label="Appearance..." - name="ChangeOutfit" - shortcut="control|O"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="appearance" /> - <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> - </menu_item_call> - <menu_item_call - label="Choose an avatar..." - name="Avatar Picker"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="avatar" /> - </menu_item_call> - <menu_item_separator/> <menu_item_check label="Inventory..." name="Inventory" @@ -76,119 +58,29 @@ parameter="experiences"/> </menu_item_call> <menu_item_call - label="My Scripts..." - name="MyScripts"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="my_scripts"/> - </menu_item_call> - <menu_item_separator/> - <menu_item_call label="Camera Controls..." name="Camera Controls"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="camera" /> </menu_item_call> - <menu - create_jump_keys="true" - label="Movement" - name="Movement" - tear_off="true"> - <menu_item_call - label="Sit Down" - layout="topleft" - shortcut="alt|shift|S" - name="Sit Down Here"> - <menu_item_call.on_click - function="Self.SitDown"/> - <menu_item_call.on_visible - function="Self.ShowSitDown"/> - <menu_item_call.on_enable - function="Self.EnableSitDown" /> - </menu_item_call> - <menu_item_call - label="Stand Up" - layout="topleft" - shortcut="alt|shift|S" - name="Stand up"> - <menu_item_call.on_click - function="Self.StandUp"/> - <menu_item_call.on_visible - function="Self.EnableStandUp"/> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> - <menu_item_check - label="Fly" - name="Fly" - shortcut="HOME"> - <menu_item_check.on_check - function="Agent.getFlying" /> - <menu_item_check.on_click - function="Agent.toggleFlying" /> - <menu_item_check.on_enable - function="Agent.enableFlying" /> - </menu_item_check> - <menu_item_call - label="Stop flying" - name="Stop flying" - shortcut="HOME"> - <menu_item_call.on_click - function="Agent.toggleFlying" /> - <menu_item_call.on_enable - function="Agent.getFlying" /> - </menu_item_call> - <menu_item_check - label="Always Run" - name="Always Run" - shortcut="control|R"> - <menu_item_check.on_check - function="World.CheckAlwaysRun" /> - <menu_item_check.on_click - function="World.AlwaysRun" /> - </menu_item_check> - <menu_item_call - label="Stop Animating Me" - name="Stop Animating My Avatar"> - <menu_item_call.on_click - function="Tools.StopAllAnimations" /> - </menu_item_call> - <menu_item_check - label="Walk / run / fly..." - name="WalkRunFly"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="moveview" /> - <menu_item_check.on_click - function="Floater.ToggleOrBringToFront" - parameter="moveview" /> - </menu_item_check> - </menu> - - <menu - create_jump_keys="true" - label="Status" - name="Status" - tear_off="true"> - <menu_item_check - name="Away" - label="Away"> - <menu_item_check.on_check - function="View.Status.CheckAway" /> - <menu_item_check.on_click - function="World.SetAway" /> - </menu_item_check> - <menu_item_check - name="Do Not Disturb" - label="Do Not Disturb"> - <menu_item_check.on_check - function="View.Status.CheckDoNotDisturb" /> - <menu_item_check.on_click - function="World.SetDoNotDisturb"/> - </menu_item_check> - - </menu> + <menu_item_separator/> + <menu_item_check + name="Away" + label="Away"> + <menu_item_check.on_check + function="View.Status.CheckAway" /> + <menu_item_check.on_click + function="World.SetAway" /> + </menu_item_check> + <menu_item_check + name="Do Not Disturb" + label="Do Not Disturb"> + <menu_item_check.on_check + function="View.Status.CheckDoNotDisturb" /> + <menu_item_check.on_click + function="World.SetDoNotDisturb"/> + </menu_item_check> <menu_item_separator/> @@ -260,6 +152,143 @@ </menu> <menu create_jump_keys="true" + label="Avatar" + name="Avatar" + tear_off="true"> + <menu_item_call + label="Complete avatars..." + name="Avatar Picker"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="avatar" /> + </menu_item_call> + <menu_item_call + label="Outfits..." + name="ChangeOutfit" + shortcut="control|O"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="appearance" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> + </menu_item_call> + <menu_item_call + label="Current outfit..." + layout="topleft" + name="Edit Outfit"> + <menu_item_call.on_click + function="EditOutfit" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> + </menu_item_call> + <menu_item_call + label="Shape..." + layout="topleft" + name="Edit My Shape"> + <menu_item_call.on_click + function="EditShape" /> + <menu_item_call.on_enable + function="Edit.EnableEditShape" /> + </menu_item_call> + <menu_item_call label="Hover height..." + layout="topleft" + name="Hover Height"> + <menu_item_call.on_click + function="HoverHeight" /> + <menu_item_call.on_enable + function="Edit.EnableHoverHeight" /> + </menu_item_call> + <menu_item_separator/> + + <menu_item_call + label="Sit / stand" + layout="topleft" + shortcut="alt|shift|S" + name="Sit stand"> + <menu_item_call.on_click + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> + </menu_item_call> + <menu_item_call + label="Fly / land" + name="Fly land" + shortcut="HOME"> + <menu_item_call.on_click + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> + </menu_item_call> + <menu_item_call + label="Stop animation" + name="Stop Animating My Avatar"> + <menu_item_call.on_click + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_check + label="Walk / run / fly..." + name="WalkRunFly"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="moveview" /> + <menu_item_check.on_click + function="Floater.ToggleOrBringToFront" + parameter="moveview" /> + </menu_item_check> + <menu_item_check + label="Always run" + name="Always Run" + shortcut="control|R"> + <menu_item_check.on_check + function="World.CheckAlwaysRun" /> + <menu_item_check.on_click + function="World.AlwaysRun" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_check + label="Gestures..." + name="Gestures" + shortcut="control|G"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="gestures" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="gestures" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_call + label="Reset skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call + label="Reset skeleton and animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_call + label="Attachment scripts..." + name="MyScripts"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="my_scripts"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="Help with avatars..." + name="Help with avatars"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="https://community.secondlife.com/search/?q=avatar"/> + </menu_item_call> + </menu> + <menu + create_jump_keys="true" label="Communicate" name="Communicate" tear_off="true"> diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index aa56b4ba63..7370dace7f 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -4,6 +4,7 @@ <menu_item_call label="Replace" layout="topleft" + visible="false" name="wear_replace"> <on_click function="Wearable.Wear" /> @@ -11,6 +12,7 @@ <menu_item_call label="Wear" layout="topleft" + visible="false" name="wear_wear"> <on_click function="Wearable.Wear" /> @@ -18,6 +20,7 @@ <menu_item_call label="Add" layout="topleft" + visible="false" name="wear_add"> <on_click function="Wearable.Add" /> @@ -25,6 +28,7 @@ <menu_item_call label="Take Off / Detach" layout="topleft" + visible="false" name="take_off_or_detach"> <on_click function="Wearable.TakeOffDetach" /> @@ -32,6 +36,7 @@ <menu_item_call label="Detach" layout="topleft" + visible="false" name="detach"> <on_click function="Attachment.Detach" /> @@ -47,6 +52,7 @@ <menu_item_call label="Take Off" layout="topleft" + visible="false" name="take_off"> <on_click function="Clothing.TakeOff" /> @@ -54,6 +60,7 @@ <menu_item_call label="Edit" layout="topleft" + visible="false" name="edit"> <on_click function="Wearable.Edit" /> @@ -61,6 +68,7 @@ <menu_item_call label="Item Profile" layout="topleft" + visible="false" name="object_profile"> <on_click function="Attachment.Profile" /> @@ -68,6 +76,7 @@ <menu_item_call label="Show Original" layout="topleft" + visible="false" name="show_original"> <on_click function="Wearable.ShowOriginal" /> @@ -75,6 +84,7 @@ <menu_item_call label="Create New" layout="topleft" + visible="false" name="create_new" translate="false"> <on_click @@ -83,6 +93,7 @@ <menu_item_call label="--no options--" layout="topleft" + visible="false" name="--no options--" translate="false"> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index dc1553e6a3..85d73ece48 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -13,7 +13,7 @@ width="333"> <string name="edit_shape_title"> - Editing Shape + Shape </string> <string name="edit_skin_title"> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index afce9f6eb5..adbeb09935 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -81,7 +81,7 @@ name="title" text_color="LtGray" top="0" - value="Edit Outfit" + value="Current Outfit" use_ellipses="true" width="275" /> |