Merge branch 'master' into DRTVWR-518-ui
commit
ac3db22abc
|
|
@ -244,9 +244,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>471b0b350955152fd87518575057dfc4</string>
|
||||
<string>322dd6c45c384d454ae14ef127984a4e</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60326/566593/bugsplat-1.0.7.542667-darwin64-542667.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65457/612879/bugsplat-1.0.7.546418-darwin64-546418.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -256,9 +256,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>70e8bf46145c4cbae6f93e8b70ba5499</string>
|
||||
<string>010a0e73c0fddaa2316411803fad8e69</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60320/566541/bugsplat-3.6.0.4.542667-windows-542667.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65456/612876/bugsplat-3.6.0.8.546418-windows-546418.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -268,16 +268,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a73696e859fad3f19f835740815a2bd3</string>
|
||||
<string>7e8530762e7b50663708a888c23b8780</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60321/566542/bugsplat-3.6.0.4.542667-windows64-542667.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65455/612874/bugsplat-3.6.0.8.546418-windows64-546418.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.0.7.542667</string>
|
||||
<string>3.6.0.8.546418</string>
|
||||
</map>
|
||||
<key>colladadom</key>
|
||||
<map>
|
||||
|
|
@ -580,9 +580,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e145f8ea99a21712434e0e868d1885dc</string>
|
||||
<string>cc26af2ebfa241891caca829a6e46b88</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62333/588183/dullahan-1.7.0.202006240858_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-544091.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65005/607316/dullahan-1.7.0.202008031101_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-546064.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -592,9 +592,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fdbbbfc377e28cba664f2b1c54ea6086</string>
|
||||
<string>4e5b9e2fe65d94e30a4f3d831c767199</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62331/588162/dullahan-1.7.0.202006241556_81.3.10_gb223419_chromium-81.0.4044.138-windows-544091.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65004/607304/dullahan-1.7.0.202008031759_81.3.10_gb223419_chromium-81.0.4044.138-windows-546064.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -604,16 +604,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>d85a32d905b199534e8feafa34b28e39</string>
|
||||
<string>6f7bf7f915f3d75dbdad08a2d41ca74e</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62332/588168/dullahan-1.7.0.202006241556_81.3.10_gb223419_chromium-81.0.4044.138-windows64-544091.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65003/607308/dullahan-1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138-windows64-546064.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.7.0.202006240858_81.3.10_gb223419_chromium-81.0.4044.138</string>
|
||||
<string>1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138</string>
|
||||
</map>
|
||||
<key>elfio</key>
|
||||
<map>
|
||||
|
|
@ -748,9 +748,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>dc4c9122de8bf77f34cfc8227d10a272</string>
|
||||
<string>89c37441a806ed80c0102d380eec6fd0</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59038/554626/fmodstudio-2.00.07.541681-darwin64-541681.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65400/612632/fmodstudio-2.00.11.546392-darwin64-546392.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -760,9 +760,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c491bdc1690f3d920c66be509ccc6ef2</string>
|
||||
<string>5283050c22d31877cd9e0afbe6feb9fc</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59039/554632/fmodstudio-2.00.07.541681-linux-541681.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65398/612630/fmodstudio-2.00.11.546392-linux-546392.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -772,9 +772,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ae75cdb1cc9da824c9e270bf97bfdd6c</string>
|
||||
<string>5a3c78f4a77ae6477986e33836725e8b</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54589/506866/fmodstudio-2.00.07.538806-linux64-538806.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65399/612631/fmodstudio-2.00.11.546392-linux64-546392.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -784,9 +784,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7f0294b038eab2d89ecc73bbf08b6d94</string>
|
||||
<string>0f44323b0d03b7d0d8a17eec83e103ce</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59042/554668/fmodstudio-2.00.07.541681-windows-541681.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65401/612647/fmodstudio-2.00.11.546392-windows-546392.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -796,16 +796,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>da2e8e2b809d8fe635ee437baa2a7386</string>
|
||||
<string>462d28eacf731a5d36ab031e7071c32a</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59041/554656/fmodstudio-2.00.07.541681-windows64-541681.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65402/612648/fmodstudio-2.00.11.546392-windows64-546392.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.00.07.541681</string>
|
||||
<string>2.00.11.546392</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
|
|
@ -2187,16 +2187,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b677ee43822212f0a27c838dc8bf3623</string>
|
||||
<string>9f4687d7d328b0c13a9e651e805e880a</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/67622/646614/llca-202009010215.548269-common-548269.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71501/691487/llca-202011010215.551526-common-551526.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>202009010215.548269</string>
|
||||
<string>202011010215.551526</string>
|
||||
</map>
|
||||
<key>llphysicsextensions_source</key>
|
||||
<map>
|
||||
|
|
@ -3495,7 +3497,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/viewer</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2014, Linden Research, Inc.</string>
|
||||
<string>Copyright (c) 2020, Linden Research, Inc.</string>
|
||||
<key>description</key>
|
||||
<string>Second Life Viewer</string>
|
||||
<key>license</key>
|
||||
|
|
|
|||
|
|
@ -223,6 +223,9 @@ Ansariel Hiller
|
|||
MAINT-8723
|
||||
SL-10385
|
||||
SL-10891
|
||||
SL-13364
|
||||
SL-13858
|
||||
SL-13697
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
CHUIBUG-191
|
||||
|
|
@ -834,7 +837,9 @@ Khyota Wulluf
|
|||
Kimar Coba
|
||||
Kithrak Kirkorian
|
||||
Kitty Barnett
|
||||
BUG-228664
|
||||
BUG-228665
|
||||
BUG-228719
|
||||
VWR-19699
|
||||
STORM-288
|
||||
STORM-799
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ LLApp::~LLApp()
|
|||
|
||||
if(mExceptionHandler != 0) delete mExceptionHandler;
|
||||
|
||||
SUBSYSTEM_CLEANUP(LLCommon);
|
||||
SUBSYSTEM_CLEANUP_DBG(LLCommon);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void ll_cleanup_apr()
|
|||
{
|
||||
gAPRInitialized = false;
|
||||
|
||||
LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
|
||||
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
|
||||
|
||||
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@
|
|||
#include "llerror.h"
|
||||
#include "llerrorcontrol.h"
|
||||
|
||||
void log_subsystem_cleanup(const char* file, int line, const char* function,
|
||||
void log_subsystem_cleanup(LLError::ELevel level,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const char* classname)
|
||||
{
|
||||
LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
|
||||
LL_VLOGS(level, "Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
|
||||
<< "calling " << classname << "::cleanupClass() in "
|
||||
<< function << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,22 @@
|
|||
// shutdown schemes.
|
||||
#define SUBSYSTEM_CLEANUP(CLASSNAME) \
|
||||
do { \
|
||||
log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
|
||||
log_subsystem_cleanup(LLError::LEVEL_INFO, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
|
||||
CLASSNAME::cleanupClass(); \
|
||||
} while (0)
|
||||
|
||||
#define SUBSYSTEM_CLEANUP_DBG(CLASSNAME) \
|
||||
do { \
|
||||
log_subsystem_cleanup(LLError::LEVEL_DEBUG, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
|
||||
CLASSNAME::cleanupClass(); \
|
||||
} while (0)
|
||||
// Use ancient do { ... } while (0) macro trick to permit a block of
|
||||
// statements with the same syntax as a single statement.
|
||||
|
||||
void log_subsystem_cleanup(const char* file, int line, const char* function,
|
||||
void log_subsystem_cleanup(LLError::ELevel level,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const char* classname);
|
||||
|
||||
#endif /* ! defined(LL_LLCLEANUP_H) */
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void LLCommon::cleanupClass()
|
|||
sMasterThreadRecorder = NULL;
|
||||
LLTrace::set_master_thread_recorder(NULL);
|
||||
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
|
||||
SUBSYSTEM_CLEANUP(LLTimer);
|
||||
SUBSYSTEM_CLEANUP_DBG(LLTimer);
|
||||
if (sAprInitialized)
|
||||
{
|
||||
ll_cleanup_apr();
|
||||
|
|
|
|||
|
|
@ -332,12 +332,9 @@ namespace LLError
|
|||
}
|
||||
// huh, that's odd, we should see one or the other prefix -- but don't
|
||||
// try to log unless logging is already initialized
|
||||
if (is_available())
|
||||
{
|
||||
// in Python, " or ".join(vector) -- but in C++, a PITB
|
||||
LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
|
||||
<< name << "'" << LL_ENDL;
|
||||
}
|
||||
// in Python, " or ".join(vector) -- but in C++, a PITB
|
||||
LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
|
||||
<< name << "'" << LL_ENDL;
|
||||
return name;
|
||||
|
||||
#else // neither GCC nor Visual Studio
|
||||
|
|
@ -438,9 +435,12 @@ namespace
|
|||
typedef std::vector<LLError::RecorderPtr> Recorders;
|
||||
typedef std::vector<LLError::CallSite*> CallSiteVector;
|
||||
|
||||
class Globals : public LLSingleton<Globals>
|
||||
class Globals
|
||||
{
|
||||
LLSINGLETON(Globals);
|
||||
public:
|
||||
static Globals* getInstance();
|
||||
protected:
|
||||
Globals();
|
||||
public:
|
||||
std::ostringstream messageStream;
|
||||
bool messageStreamInUse;
|
||||
|
|
@ -460,6 +460,16 @@ namespace
|
|||
{
|
||||
}
|
||||
|
||||
Globals* Globals::getInstance()
|
||||
{
|
||||
// According to C++11 Function-Local Initialization
|
||||
// of static variables is supposed to be thread safe
|
||||
// without risk of deadlocks.
|
||||
static Globals inst;
|
||||
|
||||
return &inst;
|
||||
}
|
||||
|
||||
void Globals::addCallSite(LLError::CallSite& site)
|
||||
{
|
||||
callSites.push_back(&site);
|
||||
|
|
@ -512,14 +522,17 @@ namespace LLError
|
|||
|
||||
typedef LLPointer<SettingsConfig> SettingsConfigPtr;
|
||||
|
||||
class Settings : public LLSingleton<Settings>
|
||||
class Settings
|
||||
{
|
||||
LLSINGLETON(Settings);
|
||||
public:
|
||||
static Settings* getInstance();
|
||||
protected:
|
||||
Settings();
|
||||
public:
|
||||
SettingsConfigPtr getSettingsConfig();
|
||||
|
||||
void reset();
|
||||
SettingsStoragePtr saveAndReset();
|
||||
SettingsStoragePtr saveAndReset();
|
||||
void restore(SettingsStoragePtr pSettingsStorage);
|
||||
|
||||
private:
|
||||
|
|
@ -553,6 +566,16 @@ namespace LLError
|
|||
{
|
||||
}
|
||||
|
||||
Settings* Settings::getInstance()
|
||||
{
|
||||
// According to C++11 Function-Local Initialization
|
||||
// of static variables is supposed to be thread safe
|
||||
// without risk of deadlocks.
|
||||
static Settings inst;
|
||||
|
||||
return &inst;
|
||||
}
|
||||
|
||||
SettingsConfigPtr Settings::getSettingsConfig()
|
||||
{
|
||||
return mSettingsConfig;
|
||||
|
|
@ -577,11 +600,6 @@ namespace LLError
|
|||
SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get()));
|
||||
mSettingsConfig = newSettingsConfig;
|
||||
}
|
||||
|
||||
bool is_available()
|
||||
{
|
||||
return Settings::instanceExists() && Globals::instanceExists();
|
||||
}
|
||||
}
|
||||
|
||||
namespace LLError
|
||||
|
|
@ -1028,7 +1046,7 @@ namespace LLError
|
|||
std::pair<boost::shared_ptr<RECORDER>, Recorders::iterator>
|
||||
findRecorderPos()
|
||||
{
|
||||
SettingsConfigPtr s = Settings::instance().getSettingsConfig();
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
// Since we promise to return an iterator, use a classic iterator
|
||||
// loop.
|
||||
auto end{s->mRecorders.end()};
|
||||
|
|
@ -1071,7 +1089,7 @@ namespace LLError
|
|||
auto found = findRecorderPos<RECORDER>();
|
||||
if (found.first)
|
||||
{
|
||||
SettingsConfigPtr s = Settings::instance().getSettingsConfig();
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
s->mRecorders.erase(found.second);
|
||||
}
|
||||
return bool(found.first);
|
||||
|
|
@ -1307,14 +1325,6 @@ namespace LLError
|
|||
return false;
|
||||
}
|
||||
|
||||
// If we hit a logging request very late during shutdown processing,
|
||||
// when either of the relevant LLSingletons has already been deleted,
|
||||
// DO NOT resurrect them.
|
||||
if (Settings::wasDeleted() || Globals::wasDeleted())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
|
||||
s->mShouldLogCallCounter++;
|
||||
|
|
@ -1353,10 +1363,8 @@ namespace LLError
|
|||
std::ostringstream* Log::out()
|
||||
{
|
||||
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
|
||||
// If we hit a logging request very late during shutdown processing,
|
||||
// when either of the relevant LLSingletons has already been deleted,
|
||||
// DO NOT resurrect them.
|
||||
if (lock.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
|
||||
|
||||
if (lock.isLocked())
|
||||
{
|
||||
Globals* g = Globals::getInstance();
|
||||
|
||||
|
|
@ -1378,14 +1386,6 @@ namespace LLError
|
|||
return;
|
||||
}
|
||||
|
||||
// If we hit a logging request very late during shutdown processing,
|
||||
// when either of the relevant LLSingletons has already been deleted,
|
||||
// DO NOT resurrect them.
|
||||
if (Settings::wasDeleted() || Globals::wasDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(out->str().c_str()) < 128)
|
||||
{
|
||||
strcpy(message, out->str().c_str());
|
||||
|
|
@ -1418,14 +1418,6 @@ namespace LLError
|
|||
return;
|
||||
}
|
||||
|
||||
// If we hit a logging request very late during shutdown processing,
|
||||
// when either of the relevant LLSingletons has already been deleted,
|
||||
// DO NOT resurrect them.
|
||||
if (Settings::wasDeleted() || Globals::wasDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Globals* g = Globals::getInstance();
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
|
||||
|
|
|
|||
|
|
@ -203,11 +203,6 @@ namespace LLError
|
|||
|
||||
LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
|
||||
LL_COMMON_API int shouldLogCallCount();
|
||||
|
||||
// Check whether Globals exists. This should only be used by LLSingleton
|
||||
// infrastructure to avoid trying to log when our internal LLSingleton is
|
||||
// unavailable -- circularity ensues.
|
||||
LL_COMMON_API bool is_available();
|
||||
};
|
||||
|
||||
#endif // LL_LLERRORCONTROL_H
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "llsingleton.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llerrorcontrol.h" // LLError::is_available()
|
||||
#include "llerrorcontrol.h"
|
||||
#include "lldependencies.h"
|
||||
#include "llexception.h"
|
||||
#include "llcoros.h"
|
||||
|
|
@ -41,8 +41,6 @@
|
|||
namespace {
|
||||
void log(LLError::ELevel level,
|
||||
const char* p1, const char* p2, const char* p3, const char* p4);
|
||||
|
||||
bool oktolog();
|
||||
} // anonymous namespace
|
||||
|
||||
// Our master list of all LLSingletons is itself an LLSingleton. We used to
|
||||
|
|
@ -279,8 +277,6 @@ void LLSingletonBase::reset_initializing(list_t::size_type size)
|
|||
|
||||
void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, const char* name)
|
||||
{
|
||||
if (oktolog())
|
||||
{
|
||||
LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';';
|
||||
if (mList)
|
||||
{
|
||||
|
|
@ -292,7 +288,6 @@ void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, cons
|
|||
}
|
||||
}
|
||||
LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLSingletonBase::capture_dependency()
|
||||
|
|
@ -455,33 +450,11 @@ void LLSingletonBase::deleteAll()
|
|||
|
||||
/*---------------------------- Logging helpers -----------------------------*/
|
||||
namespace {
|
||||
bool oktolog()
|
||||
{
|
||||
// See comments in log() below.
|
||||
return LLError::is_available();
|
||||
}
|
||||
|
||||
void log(LLError::ELevel level,
|
||||
const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
{
|
||||
// The is_available() test below ensures that we'll stop logging once
|
||||
// LLError has been cleaned up. If we had a similar portable test for
|
||||
// std::cerr, this would be a good place to use it.
|
||||
|
||||
// Check LLError::is_available() because some of LLError's infrastructure
|
||||
// is itself an LLSingleton. If that LLSingleton has not yet been
|
||||
// initialized, trying to log will engage LLSingleton machinery... and
|
||||
// around and around we go.
|
||||
if (LLError::is_available())
|
||||
{
|
||||
LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Caller may be a test program, or something else whose stderr is
|
||||
// visible to the user.
|
||||
std::cerr << p1 << p2 << p3 << p4 << std::endl;
|
||||
}
|
||||
LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
/// Exported functions
|
||||
///----------------------------------------------------------------------------
|
||||
static const std::string INV_ITEM_ID_LABEL("item_id");
|
||||
static const std::string INV_FOLDER_ID_LABEL("folder_id");
|
||||
static const std::string INV_FOLDER_ID_LABEL("cat_id");
|
||||
static const std::string INV_PARENT_ID_LABEL("parent_id");
|
||||
static const std::string INV_ASSET_TYPE_LABEL("type");
|
||||
static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
|
||||
|
|
@ -228,22 +228,6 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// exportFile should be replaced with exportLegacyStream
|
||||
// not sure whether exportLegacyStream(llofstream(fp)) would work, fp may need to get icramented...
|
||||
BOOL LLInventoryObject::exportFile(LLFILE* fp, BOOL) const
|
||||
{
|
||||
std::string uuid_str;
|
||||
fprintf(fp, "\tinv_object\t0\n\t{\n");
|
||||
mUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tobj_id\t%s\n", uuid_str.c_str());
|
||||
mParentUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
|
||||
fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
|
||||
fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
|
||||
fprintf(fp,"\t}\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLInventoryObject::exportLegacyStream(std::ostream& output_stream, BOOL) const
|
||||
{
|
||||
std::string uuid_str;
|
||||
|
|
@ -603,215 +587,6 @@ BOOL LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32
|
|||
#endif
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLInventoryItem::importFile(LLFILE* fp)
|
||||
{
|
||||
// *NOTE: Changing the buffer size will require changing the scanf
|
||||
// calls below.
|
||||
char buffer[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char keyword[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char valuestr[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char junk[MAX_STRING]; /* Flawfinder: ignore */
|
||||
BOOL success = TRUE;
|
||||
|
||||
keyword[0] = '\0';
|
||||
valuestr[0] = '\0';
|
||||
|
||||
mInventoryType = LLInventoryType::IT_NONE;
|
||||
mAssetUUID.setNull();
|
||||
while(success && (!feof(fp)))
|
||||
{
|
||||
if (fgets(buffer, MAX_STRING, fp) == NULL)
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */
|
||||
if(0 == strcmp("{",keyword))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(0 == strcmp("}", keyword))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(0 == strcmp("item_id", keyword))
|
||||
{
|
||||
mUUID.set(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("parent_id", keyword))
|
||||
{
|
||||
mParentUUID.set(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("permissions", keyword))
|
||||
{
|
||||
success = mPermissions.importFile(fp);
|
||||
}
|
||||
else if(0 == strcmp("sale_info", keyword))
|
||||
{
|
||||
// Sale info used to contain next owner perm. It is now in
|
||||
// the permissions. Thus, we read that out, and fix legacy
|
||||
// objects. It's possible this op would fail, but it
|
||||
// should pick up the vast majority of the tasks.
|
||||
BOOL has_perm_mask = FALSE;
|
||||
U32 perm_mask = 0;
|
||||
success = mSaleInfo.importFile(fp, has_perm_mask, perm_mask);
|
||||
if(has_perm_mask)
|
||||
{
|
||||
if(perm_mask == PERM_NONE)
|
||||
{
|
||||
perm_mask = mPermissions.getMaskOwner();
|
||||
}
|
||||
// fair use fix.
|
||||
if(!(perm_mask & PERM_COPY))
|
||||
{
|
||||
perm_mask |= PERM_TRANSFER;
|
||||
}
|
||||
mPermissions.setMaskNext(perm_mask);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("shadow_id", keyword))
|
||||
{
|
||||
mAssetUUID.set(valuestr);
|
||||
LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
|
||||
cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
|
||||
}
|
||||
else if(0 == strcmp("asset_id", keyword))
|
||||
{
|
||||
mAssetUUID.set(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("type", keyword))
|
||||
{
|
||||
mType = LLAssetType::lookup(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("inv_type", keyword))
|
||||
{
|
||||
mInventoryType = LLInventoryType::lookup(std::string(valuestr));
|
||||
}
|
||||
else if(0 == strcmp("flags", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mFlags);
|
||||
}
|
||||
else if(0 == strcmp("name", keyword))
|
||||
{
|
||||
//strcpy(valuestr, buffer + strlen(keyword) + 3);
|
||||
// *NOTE: Not ANSI C, but widely supported.
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %254s%254[\t]%254[^|]",
|
||||
keyword, junk, valuestr);
|
||||
|
||||
// IW: sscanf chokes and puts | in valuestr if there's no name
|
||||
if (valuestr[0] == '|')
|
||||
{
|
||||
valuestr[0] = '\000';
|
||||
}
|
||||
|
||||
mName.assign(valuestr);
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
}
|
||||
else if(0 == strcmp("desc", keyword))
|
||||
{
|
||||
//strcpy(valuestr, buffer + strlen(keyword) + 3);
|
||||
// *NOTE: Not ANSI C, but widely supported.
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %254s%254[\t]%254[^|]",
|
||||
keyword, junk, valuestr);
|
||||
|
||||
if (valuestr[0] == '|')
|
||||
{
|
||||
valuestr[0] = '\000';
|
||||
}
|
||||
|
||||
disclaimMem(mDescription);
|
||||
mDescription.assign(valuestr);
|
||||
claimMem(mDescription);
|
||||
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
|
||||
/* TODO -- ask Ian about this code
|
||||
const char *donkey = mDescription.c_str();
|
||||
if (donkey[0] == '|')
|
||||
{
|
||||
LL_ERRS() << "Donkey" << LL_ENDL;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if(0 == strcmp("creation_date", keyword))
|
||||
{
|
||||
S32 date;
|
||||
sscanf(valuestr, "%d", &date);
|
||||
mCreationDate = date;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "unknown keyword '" << keyword
|
||||
<< "' in inventory import of item " << mUUID << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// Need to convert 1.0 simstate files to a useful inventory type
|
||||
// and potentially deal with bad inventory tyes eg, a landmark
|
||||
// marked as a texture.
|
||||
if((LLInventoryType::IT_NONE == mInventoryType)
|
||||
|| !inventory_and_asset_types_match(mInventoryType, mType))
|
||||
{
|
||||
LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL;
|
||||
mInventoryType = LLInventoryType::defaultForAssetType(mType);
|
||||
}
|
||||
|
||||
mPermissions.initMasks(mInventoryType);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLInventoryItem::exportFile(LLFILE* fp, BOOL include_asset_key) const
|
||||
{
|
||||
std::string uuid_str;
|
||||
fprintf(fp, "\tinv_item\t0\n\t{\n");
|
||||
mUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\titem_id\t%s\n", uuid_str.c_str());
|
||||
mParentUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
|
||||
mPermissions.exportFile(fp);
|
||||
|
||||
// Check for permissions to see the asset id, and if so write it
|
||||
// out as an asset id. Otherwise, apply our cheesy encryption.
|
||||
if(include_asset_key)
|
||||
{
|
||||
U32 mask = mPermissions.getMaskBase();
|
||||
if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
|
||||
|| (mAssetUUID.isNull()))
|
||||
{
|
||||
mAssetUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tasset_id\t%s\n", uuid_str.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID shadow_id(mAssetUUID);
|
||||
LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
|
||||
cipher.encrypt(shadow_id.mData, UUID_BYTES);
|
||||
shadow_id.toString(uuid_str);
|
||||
fprintf(fp, "\t\tshadow_id\t%s\n", uuid_str.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID::null.toString(uuid_str);
|
||||
fprintf(fp, "\t\tasset_id\t%s\n", uuid_str.c_str());
|
||||
}
|
||||
fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
|
||||
const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
|
||||
if(!inv_type_str.empty()) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str.c_str());
|
||||
fprintf(fp, "\t\tflags\t%08x\n", mFlags);
|
||||
mSaleInfo.exportFile(fp);
|
||||
fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
|
||||
fprintf(fp, "\t\tdesc\t%s|\n", mDescription.c_str());
|
||||
fprintf(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
|
||||
fprintf(fp,"\t}\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
|
||||
{
|
||||
|
|
@ -1463,90 +1238,7 @@ void LLInventoryCategory::unpackMessage(LLMessageSystem* msg,
|
|||
msg->getStringFast(block, _PREHASH_Name, mName, block_num);
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLInventoryCategory::importFile(LLFILE* fp)
|
||||
{
|
||||
// *NOTE: Changing the buffer size will require changing the scanf
|
||||
// calls below.
|
||||
char buffer[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char keyword[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char valuestr[MAX_STRING]; /* Flawfinder: ignore */
|
||||
|
||||
keyword[0] = '\0';
|
||||
valuestr[0] = '\0';
|
||||
while(!feof(fp))
|
||||
{
|
||||
if (fgets(buffer, MAX_STRING, fp) == NULL)
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %254s %254s",
|
||||
keyword, valuestr);
|
||||
if(0 == strcmp("{",keyword))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(0 == strcmp("}", keyword))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(0 == strcmp("cat_id", keyword))
|
||||
{
|
||||
mUUID.set(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("parent_id", keyword))
|
||||
{
|
||||
mParentUUID.set(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("type", keyword))
|
||||
{
|
||||
mType = LLAssetType::lookup(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("pref_type", keyword))
|
||||
{
|
||||
mPreferredType = LLFolderType::lookup(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("name", keyword))
|
||||
{
|
||||
//strcpy(valuestr, buffer + strlen(keyword) + 3);
|
||||
// *NOTE: Not ANSI C, but widely supported.
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %254s %254[^|]",
|
||||
keyword, valuestr);
|
||||
mName.assign(valuestr);
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "unknown keyword '" << keyword
|
||||
<< "' in inventory import category " << mUUID << LL_ENDL;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLInventoryCategory::exportFile(LLFILE* fp, BOOL) const
|
||||
{
|
||||
std::string uuid_str;
|
||||
fprintf(fp, "\tinv_category\t0\n\t{\n");
|
||||
mUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tcat_id\t%s\n", uuid_str.c_str());
|
||||
mParentUUID.toString(uuid_str);
|
||||
fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
|
||||
fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
|
||||
fprintf(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType).c_str());
|
||||
fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
|
||||
fprintf(fp,"\t}\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
|
||||
{
|
||||
|
|
@ -1625,6 +1317,45 @@ BOOL LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, BOOL)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
LLSD LLInventoryCategory::exportLLSD() const
|
||||
{
|
||||
LLSD cat_data;
|
||||
cat_data[INV_FOLDER_ID_LABEL] = mUUID;
|
||||
cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
|
||||
cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
|
||||
cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
|
||||
cat_data[INV_NAME_LABEL] = mName;
|
||||
|
||||
return cat_data;
|
||||
}
|
||||
|
||||
bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
|
||||
{
|
||||
if (cat_data.has(INV_FOLDER_ID_LABEL))
|
||||
{
|
||||
setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
|
||||
}
|
||||
if (cat_data.has(INV_PARENT_ID_LABEL))
|
||||
{
|
||||
setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
|
||||
}
|
||||
if (cat_data.has(INV_ASSET_TYPE_LABEL))
|
||||
{
|
||||
setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
|
||||
{
|
||||
setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_NAME_LABEL))
|
||||
{
|
||||
mName = cat_data[INV_NAME_LABEL].asString();
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -95,8 +95,7 @@ public:
|
|||
// Implemented here so that a minimal information set can be transmitted
|
||||
// between simulator and viewer.
|
||||
//--------------------------------------------------------------------
|
||||
// virtual BOOL importFile(LLFILE* fp);
|
||||
virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
|
||||
|
||||
virtual BOOL importLegacyStream(std::istream& input_stream);
|
||||
virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
|
||||
|
||||
|
|
@ -197,8 +196,6 @@ public:
|
|||
// File Support
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
virtual BOOL importFile(LLFILE* fp);
|
||||
virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
|
||||
virtual BOOL importLegacyStream(std::istream& input_stream);
|
||||
virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
|
||||
|
||||
|
|
@ -269,11 +266,11 @@ public:
|
|||
// File Support
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
virtual BOOL importFile(LLFILE* fp);
|
||||
virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
|
||||
virtual BOOL importLegacyStream(std::istream& input_stream);
|
||||
virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
|
||||
|
||||
LLSD exportLLSD() const;
|
||||
bool importLLSD(const LLSD& cat_data);
|
||||
//--------------------------------------------------------------------
|
||||
// Member Variables
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@
|
|||
#include "llsingleton.h"
|
||||
#include "llinvtranslationbrdg.h"
|
||||
|
||||
//=========================================================================
|
||||
namespace {
|
||||
LLTranslationBridge::ptr_t sTranslator;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
struct SettingsEntry : public LLDictionaryEntry
|
||||
|
|
@ -49,7 +45,7 @@ struct SettingsEntry : public LLDictionaryEntry
|
|||
mLabel(name),
|
||||
mIconName(iconName)
|
||||
{
|
||||
std::string transdname = sTranslator->getString(mLabel);
|
||||
std::string transdname = LLSettingsType::getInstance()->mTranslator->getString(mLabel);
|
||||
if (!transdname.empty())
|
||||
{
|
||||
mLabel = transdname;
|
||||
|
|
@ -84,6 +80,16 @@ void LLSettingsDictionary::initSingleton()
|
|||
|
||||
//=========================================================================
|
||||
|
||||
LLSettingsType::LLSettingsType(LLTranslationBridge::ptr_t &trans)
|
||||
{
|
||||
mTranslator = trans;
|
||||
}
|
||||
|
||||
LLSettingsType::~LLSettingsType()
|
||||
{
|
||||
mTranslator.reset();
|
||||
}
|
||||
|
||||
LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
|
||||
{
|
||||
return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
|
||||
|
|
@ -104,13 +110,3 @@ std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
|
|||
return getDefaultName(ST_INVALID);
|
||||
return entry->mDefaultNewName;
|
||||
}
|
||||
|
||||
void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
|
||||
{
|
||||
sTranslator = trans;
|
||||
}
|
||||
|
||||
void LLSettingsType::cleanupClass()
|
||||
{
|
||||
sTranslator.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,15 @@
|
|||
|
||||
#include "llinventorytype.h"
|
||||
#include "llinvtranslationbrdg.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
class LLSettingsType
|
||||
class LLSettingsType : public LLParamSingleton<LLSettingsType>
|
||||
{
|
||||
LLSINGLETON(LLSettingsType, LLTranslationBridge::ptr_t &trans);
|
||||
~LLSettingsType();
|
||||
|
||||
friend struct SettingsEntry;
|
||||
|
||||
public:
|
||||
enum type_e
|
||||
{
|
||||
|
|
@ -48,8 +54,9 @@ public:
|
|||
static LLInventoryType::EIconName getIconName(type_e type);
|
||||
static std::string getDefaultName(type_e type);
|
||||
|
||||
static void initClass(LLTranslationBridge::ptr_t &trans);
|
||||
static void cleanupClass();
|
||||
protected:
|
||||
|
||||
LLTranslationBridge::ptr_t mTranslator;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -565,148 +565,6 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// File support
|
||||
//
|
||||
|
||||
BOOL LLPermissions::importFile(LLFILE* fp)
|
||||
{
|
||||
init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
|
||||
const S32 BUFSIZE = 16384;
|
||||
|
||||
// *NOTE: Changing the buffer size will require changing the scanf
|
||||
// calls below.
|
||||
char buffer[BUFSIZE]; /* Flawfinder: ignore */
|
||||
char keyword[256]; /* Flawfinder: ignore */
|
||||
char valuestr[256]; /* Flawfinder: ignore */
|
||||
char uuid_str[256]; /* Flawfinder: ignore */
|
||||
U32 mask;
|
||||
|
||||
keyword[0] = '\0';
|
||||
valuestr[0] = '\0';
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
if (fgets(buffer, BUFSIZE, fp) == NULL)
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %255s %255s",
|
||||
keyword, valuestr);
|
||||
if (!strcmp("{", keyword))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("}",keyword))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (!strcmp("creator_mask", keyword))
|
||||
{
|
||||
// legacy support for "creator" masks
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskBase = mask;
|
||||
fixFairUse();
|
||||
}
|
||||
else if (!strcmp("base_mask", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskBase = mask;
|
||||
//fixFairUse();
|
||||
}
|
||||
else if (!strcmp("owner_mask", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskOwner = mask;
|
||||
}
|
||||
else if (!strcmp("group_mask", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskGroup = mask;
|
||||
}
|
||||
else if (!strcmp("everyone_mask", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskEveryone = mask;
|
||||
}
|
||||
else if (!strcmp("next_owner_mask", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%x", &mask);
|
||||
mMaskNextOwner = mask;
|
||||
}
|
||||
else if (!strcmp("creator_id", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
|
||||
mCreator.set(uuid_str);
|
||||
}
|
||||
else if (!strcmp("owner_id", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
|
||||
mOwner.set(uuid_str);
|
||||
}
|
||||
else if (!strcmp("last_owner_id", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
|
||||
mLastOwner.set(uuid_str);
|
||||
}
|
||||
else if (!strcmp("group_id", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
|
||||
mGroup.set(uuid_str);
|
||||
}
|
||||
else if (!strcmp("group_owned", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%d", &mask);
|
||||
if(mask) mIsGroupOwned = true;
|
||||
else mIsGroupOwned = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "unknown keyword " << keyword << " in permissions import" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
fix();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPermissions::exportFile(LLFILE* fp) const
|
||||
{
|
||||
std::string uuid_str;
|
||||
|
||||
fprintf(fp, "\tpermissions 0\n");
|
||||
fprintf(fp, "\t{\n");
|
||||
|
||||
fprintf(fp, "\t\tbase_mask\t%08x\n", mMaskBase);
|
||||
fprintf(fp, "\t\towner_mask\t%08x\n", mMaskOwner);
|
||||
fprintf(fp, "\t\tgroup_mask\t%08x\n", mMaskGroup);
|
||||
fprintf(fp, "\t\teveryone_mask\t%08x\n", mMaskEveryone);
|
||||
fprintf(fp, "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
|
||||
|
||||
mCreator.toString(uuid_str);
|
||||
fprintf(fp, "\t\tcreator_id\t%s\n", uuid_str.c_str());
|
||||
|
||||
mOwner.toString(uuid_str);
|
||||
fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str());
|
||||
|
||||
mLastOwner.toString(uuid_str);
|
||||
fprintf(fp, "\t\tlast_owner_id\t%s\n", uuid_str.c_str());
|
||||
|
||||
mGroup.toString(uuid_str);
|
||||
fprintf(fp, "\t\tgroup_id\t%s\n", uuid_str.c_str());
|
||||
|
||||
if(mIsGroupOwned)
|
||||
{
|
||||
fprintf(fp, "\t\tgroup_owned\t1\n");
|
||||
}
|
||||
fprintf(fp,"\t}\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
|
||||
{
|
||||
init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
|
||||
|
|
|
|||
|
|
@ -311,10 +311,6 @@ public:
|
|||
void packMessage(LLMessageSystem* msg) const;
|
||||
void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
|
||||
|
||||
// Load/save support
|
||||
BOOL importFile(LLFILE* fp);
|
||||
BOOL exportFile(LLFILE* fp) const;
|
||||
|
||||
BOOL importLegacyStream(std::istream& input_stream);
|
||||
BOOL exportLegacyStream(std::ostream& output_stream) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,16 +78,6 @@ U32 LLSaleInfo::getCRC32() const
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLSaleInfo::exportFile(LLFILE* fp) const
|
||||
{
|
||||
fprintf(fp, "\tsale_info\t0\n\t{\n");
|
||||
fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
|
||||
fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
|
||||
fprintf(fp,"\t}\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
|
||||
{
|
||||
output_stream << "\tsale_info\t0\n\t{\n";
|
||||
|
|
@ -129,69 +119,6 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
|
||||
// because I can't find any non-test code references to it. 2009-05-04 JC
|
||||
|
||||
BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
|
||||
{
|
||||
has_perm_mask = FALSE;
|
||||
|
||||
// *NOTE: Changing the buffer size will require changing the scanf
|
||||
// calls below.
|
||||
char buffer[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char keyword[MAX_STRING]; /* Flawfinder: ignore */
|
||||
char valuestr[MAX_STRING]; /* Flawfinder: ignore */
|
||||
BOOL success = TRUE;
|
||||
|
||||
keyword[0] = '\0';
|
||||
valuestr[0] = '\0';
|
||||
while(success && (!feof(fp)))
|
||||
{
|
||||
if (fgets(buffer, MAX_STRING, fp) == NULL)
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
sscanf( /* Flawfinder: ignore */
|
||||
buffer,
|
||||
" %254s %254s",
|
||||
keyword, valuestr);
|
||||
if(!keyword[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(0 == strcmp("{",keyword))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(0 == strcmp("}", keyword))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(0 == strcmp("sale_type", keyword))
|
||||
{
|
||||
mSaleType = lookup(valuestr);
|
||||
}
|
||||
else if(0 == strcmp("sale_price", keyword))
|
||||
{
|
||||
sscanf(valuestr, "%d", &mSalePrice);
|
||||
mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
|
||||
}
|
||||
else if (!strcmp("perm_mask", keyword))
|
||||
{
|
||||
//LL_INFOS() << "found deprecated keyword perm_mask" << LL_ENDL;
|
||||
has_perm_mask = TRUE;
|
||||
sscanf(valuestr, "%x", &perm_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "unknown keyword '" << keyword
|
||||
<< "' in sale info import" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
|
||||
{
|
||||
has_perm_mask = FALSE;
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@ public:
|
|||
void setSalePrice(S32 price);
|
||||
//void setNextOwnerPermMask(U32 mask) { mNextOwnerPermMask = mask; }
|
||||
|
||||
|
||||
// file serialization
|
||||
BOOL exportFile(LLFILE* fp) const;
|
||||
BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask);
|
||||
|
||||
BOOL exportLegacyStream(std::ostream& output_stream) const;
|
||||
LLSD asLLSD() const;
|
||||
operator LLSD() const { return asLLSD(); }
|
||||
|
|
|
|||
|
|
@ -359,7 +359,6 @@ protected:
|
|||
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
|
||||
|
||||
LLSD mSettings;
|
||||
bool mIsValid;
|
||||
|
||||
LLSD cloneSettings() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "llsd.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
#include "../llinventory.h"
|
||||
|
||||
#include "../test/lltut.h"
|
||||
|
||||
|
||||
|
|
@ -320,27 +320,39 @@ namespace tut
|
|||
template<> template<>
|
||||
void inventory_object::test<7>()
|
||||
{
|
||||
LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
|
||||
if(!fp)
|
||||
std::string filename("linden_file.dat");
|
||||
llofstream fileXML(filename.c_str());
|
||||
if (!fileXML.is_open())
|
||||
{
|
||||
LL_ERRS() << "file could not be opened\n" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
|
||||
src1->exportFile(fp, TRUE);
|
||||
fclose(fp);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
|
||||
fp = LLFile::fopen("linden_file.dat","r+");
|
||||
if(!fp)
|
||||
|
||||
LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
|
||||
llifstream file(filename.c_str());
|
||||
if (!file.is_open())
|
||||
{
|
||||
LL_ERRS() << "file could not be opened\n" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
src2->importFile(fp);
|
||||
fclose(fp);
|
||||
std::string line;
|
||||
LLPointer<LLSDParser> parser = new LLSDNotationParser();
|
||||
std::getline(file, line);
|
||||
LLSD s_item;
|
||||
std::istringstream iss(line);
|
||||
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
|
||||
{
|
||||
LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
src2->fromLLSD(s_item);
|
||||
|
||||
file.close();
|
||||
|
||||
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
||||
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
||||
|
|
@ -457,27 +469,39 @@ namespace tut
|
|||
template<> template<>
|
||||
void inventory_object::test<13>()
|
||||
{
|
||||
LLFILE* fp = LLFile::fopen("linden_file.dat","w");
|
||||
if(!fp)
|
||||
std::string filename("linden_file.dat");
|
||||
llofstream fileXML(filename.c_str());
|
||||
if (!fileXML.is_open())
|
||||
{
|
||||
LL_ERRS() << "file coudnt be opened\n" << LL_ENDL;
|
||||
LL_ERRS() << "file could not be opened\n" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
|
||||
src1->exportFile(fp, TRUE);
|
||||
fclose(fp);
|
||||
|
||||
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
||||
fp = LLFile::fopen("linden_file.dat","r");
|
||||
if(!fp)
|
||||
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
llifstream file(filename.c_str());
|
||||
if (!file.is_open())
|
||||
{
|
||||
LL_ERRS() << "file coudnt be opened\n" << LL_ENDL;
|
||||
LL_ERRS() << "file could not be opened\n" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
src2->importFile(fp);
|
||||
fclose(fp);
|
||||
std::string line;
|
||||
LLPointer<LLSDParser> parser = new LLSDNotationParser();
|
||||
std::getline(file, line);
|
||||
LLSD s_item;
|
||||
std::istringstream iss(line);
|
||||
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
|
||||
{
|
||||
LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
||||
src2->importLLSD(s_item);
|
||||
|
||||
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
||||
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
|
|||
}
|
||||
|
||||
// The queue should never fill up.
|
||||
LL_ERRS("CoProcMgr") << "Enqueue failed (" << unsigned(pushed) << ")" << LL_ENDL;
|
||||
LL_ERRS("CoProcMgr") << "Enqueue into '" << name << "' failed (" << unsigned(pushed) << ")" << LL_ENDL;
|
||||
return {}; // never executed, pacify the compiler
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -857,12 +857,12 @@ void LLPluginClassMedia::paste()
|
|||
}
|
||||
|
||||
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
|
||||
const std::string &user_data_path_cookies,
|
||||
const std::string &username,
|
||||
const std::string &user_data_path_cef_log)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
|
||||
message.setValue("cache_path", user_data_path_cache);
|
||||
message.setValue("cookies_path", user_data_path_cookies);
|
||||
message.setValue("cache_path", user_data_path_cache);
|
||||
message.setValue("username", username); // cef shares cache between users but creates user-based contexts
|
||||
message.setValue("cef_log_file", user_data_path_cef_log);
|
||||
|
||||
bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ public:
|
|||
bool canPaste() const { return mCanPaste; };
|
||||
|
||||
// These can be called before init(), and they will be queued and sent before the media init message.
|
||||
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
|
||||
void setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log);
|
||||
void setLanguageCode(const std::string &language_code);
|
||||
void setPluginsEnabled(const bool enabled);
|
||||
void setJavascriptEnabled(const bool enabled);
|
||||
|
|
|
|||
|
|
@ -225,6 +225,18 @@ void LLPluginProcessChild::idle(void)
|
|||
}
|
||||
setState(STATE_UNLOADED);
|
||||
}
|
||||
|
||||
if (mInstance)
|
||||
{
|
||||
// Provide some time to the plugin
|
||||
// example: CEF on "cleanup" sets shutdown request, but it still needs idle loop to actually shutdown
|
||||
LLPluginMessage message("base", "idle");
|
||||
message.setValueReal("time", PLUGIN_IDLE_SECONDS);
|
||||
sendMessageToPlugin(message);
|
||||
|
||||
mInstance->idle();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_UNLOADED:
|
||||
|
|
|
|||
|
|
@ -2700,10 +2700,11 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w
|
|||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
// Expose desired use of high-performance graphics processor to Optimus driver
|
||||
// Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
|
||||
extern "C"
|
||||
{
|
||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
{
|
||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1193,7 +1193,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool sucsess = true;
|
||||
bool success = true;
|
||||
|
||||
mEmpty = true;
|
||||
|
||||
|
|
@ -1215,9 +1215,9 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
|
|||
|
||||
if (!mMappedData)
|
||||
{
|
||||
sucsess = false;
|
||||
success = false;
|
||||
}
|
||||
return sucsess;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::createGLIndices(U32 size)
|
||||
|
|
@ -1232,7 +1232,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool sucsess = true;
|
||||
bool success = true;
|
||||
|
||||
mEmpty = true;
|
||||
|
||||
|
|
@ -1257,9 +1257,9 @@ bool LLVertexBuffer::createGLIndices(U32 size)
|
|||
|
||||
if (!mMappedIndexData)
|
||||
{
|
||||
sucsess = false;
|
||||
success = false;
|
||||
}
|
||||
return sucsess;
|
||||
return success;
|
||||
}
|
||||
|
||||
void LLVertexBuffer::destroyGLBuffer()
|
||||
|
|
@ -1306,7 +1306,7 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
|
|||
{
|
||||
llassert(nverts >= 0);
|
||||
|
||||
bool sucsess = true;
|
||||
bool success = true;
|
||||
|
||||
if (nverts > 65536)
|
||||
{
|
||||
|
|
@ -1318,34 +1318,34 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
|
|||
|
||||
if (needed_size > mSize || needed_size <= mSize/2)
|
||||
{
|
||||
sucsess &= createGLBuffer(needed_size);
|
||||
success &= createGLBuffer(needed_size);
|
||||
}
|
||||
|
||||
sVertexCount -= mNumVerts;
|
||||
mNumVerts = nverts;
|
||||
sVertexCount += mNumVerts;
|
||||
|
||||
return sucsess;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::updateNumIndices(S32 nindices)
|
||||
{
|
||||
llassert(nindices >= 0);
|
||||
|
||||
bool sucsess = true;
|
||||
bool success = true;
|
||||
|
||||
U32 needed_size = sizeof(U16) * nindices;
|
||||
|
||||
if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
|
||||
{
|
||||
sucsess &= createGLIndices(needed_size);
|
||||
success &= createGLIndices(needed_size);
|
||||
}
|
||||
|
||||
sIndexCount -= mNumIndices;
|
||||
mNumIndices = nindices;
|
||||
sIndexCount += mNumIndices;
|
||||
|
||||
return sucsess;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
|
|
@ -1358,10 +1358,10 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
|||
LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
|
||||
}
|
||||
|
||||
bool sucsess = true;
|
||||
bool success = true;
|
||||
|
||||
sucsess &= updateNumVerts(nverts);
|
||||
sucsess &= updateNumIndices(nindices);
|
||||
success &= updateNumVerts(nverts);
|
||||
success &= updateNumIndices(nindices);
|
||||
|
||||
if (create && (nverts || nindices))
|
||||
{
|
||||
|
|
@ -1377,7 +1377,7 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
|||
}
|
||||
}
|
||||
|
||||
return sucsess;
|
||||
return success;
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
|
|||
, mTabComparator( NULL )
|
||||
, mNoVisibleTabsHelpText(NULL)
|
||||
, mNoVisibleTabsOrigString(params.no_visible_tabs_text.initial_value().asString())
|
||||
, mSkipScrollToChild(false)
|
||||
{
|
||||
initNoTabsWidget(params.no_matched_tabs_text);
|
||||
|
||||
|
|
@ -659,7 +660,7 @@ void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
|
|||
// virtual
|
||||
void LLAccordionCtrl::onUpdateScrollToChild(const LLUICtrl *cntrl)
|
||||
{
|
||||
if (mScrollbar && mScrollbar->getVisible())
|
||||
if (mScrollbar && mScrollbar->getVisible() && !mSkipScrollToChild)
|
||||
{
|
||||
// same as scrollToShowRect
|
||||
LLRect rect;
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ public:
|
|||
|
||||
bool getFitParent() const {return mFitParent;}
|
||||
|
||||
void setSkipScrollToChild(bool skip) { mSkipScrollToChild = skip; }
|
||||
|
||||
private:
|
||||
void initNoTabsWidget(const LLTextBox::Params& tb_params);
|
||||
void updateNoTabsHelpTextVisibility();
|
||||
|
|
@ -183,6 +185,8 @@ private:
|
|||
F32 mAutoScrollRate;
|
||||
LLTextBox* mNoVisibleTabsHelpText;
|
||||
|
||||
bool mSkipScrollToChild;
|
||||
|
||||
std::string mNoMatchedTabsOrigString;
|
||||
std::string mNoVisibleTabsOrigString;
|
||||
|
||||
|
|
|
|||
|
|
@ -342,7 +342,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
|
|||
void LLFolderView::filter( LLFolderViewFilter& filter )
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_FILTER);
|
||||
filter.resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
|
||||
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
|
||||
filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
|
||||
|
||||
// Note: we filter the model, not the view
|
||||
getViewModelItem()->filter(filter);
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
: LLView(p),
|
||||
mLabelWidth(0),
|
||||
mLabelWidthDirty(false),
|
||||
mSuffixNeedsRefresh(false),
|
||||
mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
|
||||
mParentFolder( NULL ),
|
||||
mIsSelected( FALSE ),
|
||||
|
|
@ -181,11 +182,25 @@ LLFolderViewItem::~LLFolderViewItem()
|
|||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
{
|
||||
refresh();
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi.getDisplayName();
|
||||
setToolTip(vmi.getName());
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
|
||||
// Don't do full refresh on constructor if it is possible to avoid
|
||||
// it significantly slows down bulk view creation.
|
||||
// Todo: Ideally we need to move getDisplayName() out of constructor as well.
|
||||
// Like: make a logic that will let filter update search string,
|
||||
// while LLFolderViewItem::arrange() updates visual part
|
||||
mSuffixNeedsRefresh = true;
|
||||
mLabelWidthDirty = true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
LLFolderView* LLFolderViewItem::getRoot()
|
||||
{
|
||||
return mRoot;
|
||||
|
|
@ -280,24 +295,51 @@ BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
|
|||
|
||||
void LLFolderViewItem::refresh()
|
||||
{
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
|
||||
mLabel = vmi.getDisplayName();
|
||||
mLabel = vmi.getDisplayName();
|
||||
setToolTip(vmi.getName());
|
||||
// icons are slightly expensive to get, can be optimized
|
||||
// see LLInventoryIcon::getIcon()
|
||||
mIcon = vmi.getIcon();
|
||||
mIconOpen = vmi.getIconOpen();
|
||||
mIconOverlay = vmi.getIconOverlay();
|
||||
|
||||
setToolTip(vmi.getName());
|
||||
mIcon = vmi.getIcon();
|
||||
mIconOpen = vmi.getIconOpen();
|
||||
mIconOverlay = vmi.getIconOverlay();
|
||||
if (mRoot->useLabelSuffix())
|
||||
{
|
||||
// Very Expensive!
|
||||
// Can do a number of expensive checks, like checking active motions, wearables or friend list
|
||||
mLabelStyle = vmi.getLabelStyle();
|
||||
mLabelSuffix = vmi.getLabelSuffix();
|
||||
}
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
|
||||
mLabelWidthDirty = true;
|
||||
mSuffixNeedsRefresh = false;
|
||||
}
|
||||
|
||||
void LLFolderViewItem::refreshSuffix()
|
||||
{
|
||||
LLFolderViewModelItem const* vmi = getViewModelItem();
|
||||
|
||||
// icons are slightly expensive to get, can be optimized
|
||||
// see LLInventoryIcon::getIcon()
|
||||
mIcon = vmi->getIcon();
|
||||
mIconOpen = vmi->getIconOpen();
|
||||
mIconOverlay = vmi->getIconOverlay();
|
||||
|
||||
if (mRoot->useLabelSuffix())
|
||||
{
|
||||
mLabelStyle = vmi.getLabelStyle();
|
||||
mLabelSuffix = vmi.getLabelSuffix();
|
||||
// Very Expensive!
|
||||
// Can do a number of expensive checks, like checking active motions, wearables or friend list
|
||||
mLabelStyle = vmi->getLabelStyle();
|
||||
mLabelSuffix = vmi->getLabelSuffix();
|
||||
}
|
||||
|
||||
mLabelWidthDirty = true;
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
mLabelWidthDirty = true;
|
||||
mSuffixNeedsRefresh = false;
|
||||
}
|
||||
|
||||
// Utility function for LLFolderView
|
||||
|
|
@ -348,6 +390,12 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
|
|||
: 0;
|
||||
if (mLabelWidthDirty)
|
||||
{
|
||||
if (mSuffixNeedsRefresh)
|
||||
{
|
||||
// Expensive. But despite refreshing label,
|
||||
// it is purely visual, so it is fine to do at our laisure
|
||||
refreshSuffix();
|
||||
}
|
||||
mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight;
|
||||
mLabelWidthDirty = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ protected:
|
|||
LLPointer<LLFolderViewModelItem> mViewModelItem;
|
||||
LLFontGL::StyleFlags mLabelStyle;
|
||||
std::string mLabelSuffix;
|
||||
bool mSuffixNeedsRefresh; //suffix and icons
|
||||
LLUIImagePtr mIcon,
|
||||
mIconOpen,
|
||||
mIconOverlay;
|
||||
|
|
@ -266,8 +267,13 @@ public:
|
|||
virtual BOOL passedFilter(S32 filter_generation = -1);
|
||||
virtual BOOL isPotentiallyVisible(S32 filter_generation = -1);
|
||||
|
||||
// refresh information from the object being viewed.
|
||||
virtual void refresh();
|
||||
// refresh information from the object being viewed.
|
||||
// refreshes label, suffixes and sets icons. Expensive!
|
||||
// Causes filter update
|
||||
virtual void refresh();
|
||||
// refreshes suffixes and sets icons. Expensive!
|
||||
// Does not need filter update
|
||||
virtual void refreshSuffix();
|
||||
|
||||
// LLView functionality
|
||||
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ std::string LLFolderViewModelCommon::getStatusText()
|
|||
|
||||
void LLFolderViewModelCommon::filter()
|
||||
{
|
||||
getFilter().resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
|
||||
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
getFilter().resetTime(llclamp(filter_visible(), 1, 100));
|
||||
mFolderView->getViewModelItem()->filter(getFilter());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -285,17 +285,7 @@ public:
|
|||
typedef std::list<LLFolderViewModelItem*> child_list_t;
|
||||
|
||||
virtual void addChild(LLFolderViewModelItem* child)
|
||||
{
|
||||
// Avoid duplicates: bail out if that child is already present in the list
|
||||
// Note: this happens when models are created before views
|
||||
child_list_t::const_iterator iter;
|
||||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
if (child == *iter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
mChildren.push_back(child);
|
||||
child->setParent(this);
|
||||
dirtyFilter();
|
||||
|
|
|
|||
|
|
@ -49,8 +49,6 @@ LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
|
|||
LLSpellChecker::LLSpellChecker()
|
||||
: mHunspell(NULL)
|
||||
{
|
||||
// Load initial dictionary information
|
||||
refreshDictionaryMap();
|
||||
}
|
||||
|
||||
LLSpellChecker::~LLSpellChecker()
|
||||
|
|
@ -58,6 +56,12 @@ LLSpellChecker::~LLSpellChecker()
|
|||
delete mHunspell;
|
||||
}
|
||||
|
||||
void LLSpellChecker::initSingleton()
|
||||
{
|
||||
// Load initial dictionary information
|
||||
refreshDictionaryMap();
|
||||
}
|
||||
|
||||
bool LLSpellChecker::checkSpelling(const std::string& word) const
|
||||
{
|
||||
if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) )
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
protected:
|
||||
void addToDictFile(const std::string& dict_path, const std::string& word);
|
||||
void initHunspell(const std::string& dict_language);
|
||||
void initSingleton();
|
||||
|
||||
public:
|
||||
typedef std::list<std::string> dict_list_t;
|
||||
|
|
|
|||
|
|
@ -454,13 +454,17 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
|
|||
}
|
||||
|
||||
//
|
||||
// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
|
||||
// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ *secondlifegrid.net/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
|
||||
//
|
||||
LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
|
||||
{
|
||||
mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com)"
|
||||
"|"
|
||||
"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?))"
|
||||
"(http://([-\\w\\.]*\\.)?secondlifegrid\\.net)"
|
||||
"|"
|
||||
"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
|
||||
"|"
|
||||
"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
|
||||
"\\/\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
|
||||
|
|
@ -495,12 +499,14 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
|
|||
}
|
||||
|
||||
//
|
||||
// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com and *tilia-inc.com urls to substitute icon 'hand.png' before link
|
||||
// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com *secondlifegrid.net and *tilia-inc.com urls to substitute icon 'hand.png' before link
|
||||
//
|
||||
LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
|
||||
{
|
||||
mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)"
|
||||
"|"
|
||||
"https?://([-\\w\\.]*\\.)?secondlifegrid\\.net(?!\\S)",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
|
||||
mIcon = "Hand";
|
||||
mMenuName = "menu_url_http.xml";
|
||||
|
|
|
|||
|
|
@ -784,9 +784,6 @@ void LLWindowWin32::close()
|
|||
resetDisplayResolution();
|
||||
}
|
||||
|
||||
// Don't process events in our mainWindowProc any longer.
|
||||
SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL);
|
||||
|
||||
// Make sure cursor is visible and we haven't mangled the clipping state.
|
||||
showCursor();
|
||||
setMouseClipping(FALSE);
|
||||
|
|
@ -832,16 +829,24 @@ void LLWindowWin32::close()
|
|||
|
||||
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
|
||||
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
ShowWindow(mWindowHandle, SW_HIDE);
|
||||
if (IsWindow(mWindowHandle))
|
||||
{
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
ShowWindow(mWindowHandle, SW_HIDE);
|
||||
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
|
||||
mCallbacks->translateString("MBShutdownErr"),
|
||||
OSMB_OK);
|
||||
}
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
|
||||
mCallbacks->translateString("MBShutdownErr"),
|
||||
OSMB_OK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something killed the window while we were busy destroying gl or handle somehow got broken
|
||||
LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
|
||||
}
|
||||
|
||||
mWindowHandle = NULL;
|
||||
}
|
||||
|
|
@ -1133,7 +1138,10 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
<< " Height: " << (window_rect.bottom - window_rect.top)
|
||||
<< " Fullscreen: " << mFullscreen
|
||||
<< LL_ENDL;
|
||||
DestroyWindow(mWindowHandle);
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
|
||||
}
|
||||
mWindowHandle = CreateWindowEx(dw_ex_style,
|
||||
mWindowClassName,
|
||||
mWindowTitle,
|
||||
|
|
@ -1453,8 +1461,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
|
|||
ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
|
||||
mhDC = 0; // Zero The Device Context
|
||||
}
|
||||
DestroyWindow (mWindowHandle); // Destroy The Window
|
||||
|
||||
|
||||
// Destroy The Window
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;
|
||||
}
|
||||
|
||||
mWindowHandle = CreateWindowEx(dw_ex_style,
|
||||
mWindowClassName,
|
||||
|
|
@ -3397,7 +3409,10 @@ void LLSplashScreenWin32::hideImpl()
|
|||
{
|
||||
if (mWindow)
|
||||
{
|
||||
DestroyWindow(mWindow);
|
||||
if (!destroy_window_handler(mWindow))
|
||||
{
|
||||
LL_WARNS("Window") << "Failed to properly close splash screen window!" << LL_ENDL;
|
||||
}
|
||||
mWindow = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,9 @@ private:
|
|||
bool mCanCut;
|
||||
bool mCanCopy;
|
||||
bool mCanPaste;
|
||||
std::string mRootCachePath;
|
||||
std::string mCachePath;
|
||||
std::string mContextCachePath;
|
||||
std::string mCefLogFile;
|
||||
bool mCefLogVerbose;
|
||||
std::vector<std::string> mPickedFiles;
|
||||
|
|
@ -458,7 +460,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
|||
}
|
||||
else if (message_name == "cleanup")
|
||||
{
|
||||
mVolumeCatcher.setVolume(0); // Hack: masks CEF exit issues
|
||||
mCEFLib->requestExit();
|
||||
}
|
||||
else if (message_name == "force_exit")
|
||||
|
|
@ -527,7 +528,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
|||
settings.accept_language_list = mHostLanguage;
|
||||
settings.background_color = 0xffffffff;
|
||||
settings.cache_enabled = true;
|
||||
settings.root_cache_path = mRootCachePath;
|
||||
settings.cache_path = mCachePath;
|
||||
settings.context_cache_path = mContextCachePath;
|
||||
settings.cookies_enabled = mCookiesEnabled;
|
||||
settings.disable_gpu = mDisableGPU;
|
||||
#if LL_DARWIN
|
||||
|
|
@ -583,9 +586,25 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
|||
else if (message_name == "set_user_data_path")
|
||||
{
|
||||
std::string user_data_path_cache = message_in.getValue("cache_path");
|
||||
std::string user_data_path_cookies = message_in.getValue("cookies_path");
|
||||
std::string subfolder = message_in.getValue("username");
|
||||
|
||||
mCachePath = user_data_path_cache + "cef_cache";
|
||||
mRootCachePath = user_data_path_cache + "cef_cache";
|
||||
if (!subfolder.empty())
|
||||
{
|
||||
std::string delim;
|
||||
#if LL_WINDOWS
|
||||
// media plugin doesn't have access to gDirUtilp
|
||||
delim = "\\";
|
||||
#else
|
||||
delim = "/";
|
||||
#endif
|
||||
mCachePath = mRootCachePath + delim + subfolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCachePath = mRootCachePath;
|
||||
}
|
||||
mContextCachePath = ""; // disabled by ""
|
||||
mCefLogFile = message_in.getValue("cef_log_file");
|
||||
mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2149,7 +2149,7 @@ if (DARWIN)
|
|||
set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2019")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2020")
|
||||
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
|
||||
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication")
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.4.11
|
||||
6.4.12
|
||||
|
|
|
|||
|
|
@ -30,12 +30,6 @@
|
|||
#include "llhandle.h"
|
||||
|
||||
#include "llaccountingcost.h"
|
||||
#include "httpcommon.h"
|
||||
#include "llcoros.h"
|
||||
#include "lleventcoro.h"
|
||||
#include "httprequest.h"
|
||||
#include "httpheaders.h"
|
||||
#include "httpoptions.h"
|
||||
|
||||
//===============================================================================
|
||||
// An interface class for panels which display the parcel accounting information.
|
||||
|
|
|
|||
|
|
@ -137,6 +137,10 @@ public:
|
|||
EStatus getStatus() const {return mStatus;};
|
||||
void setStatus(EStatus pStatus) {mStatus = pStatus;};
|
||||
|
||||
static std::map<S32, std::string> sTeleportStatusName;
|
||||
static const std::string& statusName(EStatus status);
|
||||
virtual void toOstream(std::ostream& os) const;
|
||||
|
||||
virtual bool canRestartTeleport();
|
||||
|
||||
virtual void startTeleport() = 0;
|
||||
|
|
@ -148,12 +152,19 @@ private:
|
|||
EStatus mStatus;
|
||||
};
|
||||
|
||||
std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending, "kPending" },
|
||||
{ kStarted, "kStarted" },
|
||||
{ kFailed, "kFailed" },
|
||||
{ kRestartPending, "kRestartPending"} };
|
||||
|
||||
class LLTeleportRequestViaLandmark : public LLTeleportRequest
|
||||
{
|
||||
public:
|
||||
LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
|
||||
virtual ~LLTeleportRequestViaLandmark();
|
||||
|
||||
virtual void toOstream(std::ostream& os) const;
|
||||
|
||||
virtual bool canRestartTeleport();
|
||||
|
||||
virtual void startTeleport();
|
||||
|
|
@ -172,6 +183,8 @@ public:
|
|||
LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
|
||||
virtual ~LLTeleportRequestViaLure();
|
||||
|
||||
virtual void toOstream(std::ostream& os) const;
|
||||
|
||||
virtual bool canRestartTeleport();
|
||||
|
||||
virtual void startTeleport();
|
||||
|
|
@ -189,6 +202,8 @@ public:
|
|||
LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
|
||||
virtual ~LLTeleportRequestViaLocation();
|
||||
|
||||
virtual void toOstream(std::ostream& os) const;
|
||||
|
||||
virtual bool canRestartTeleport();
|
||||
|
||||
virtual void startTeleport();
|
||||
|
|
@ -208,6 +223,8 @@ public:
|
|||
LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
|
||||
virtual ~LLTeleportRequestViaLocationLookAt();
|
||||
|
||||
virtual void toOstream(std::ostream& os) const;
|
||||
|
||||
virtual bool canRestartTeleport();
|
||||
|
||||
virtual void startTeleport();
|
||||
|
|
@ -492,6 +509,8 @@ void LLAgent::init()
|
|||
void LLAgent::cleanup()
|
||||
{
|
||||
mRegionp = NULL;
|
||||
mTeleportRequest = NULL;
|
||||
mTeleportCanceled = NULL;
|
||||
if (mTeleportFinishedSlot.connected())
|
||||
{
|
||||
mTeleportFinishedSlot.disconnect();
|
||||
|
|
@ -867,7 +886,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
if (mRegionp != regionp)
|
||||
{
|
||||
|
||||
LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() << LL_ENDL;
|
||||
LL_INFOS("AgentLocation","Teleport") << "Moving agent into region: handle " << regionp->getHandle()
|
||||
<< " id " << regionp->getRegionID()
|
||||
<< " name " << regionp->getName()
|
||||
<< " previous region "
|
||||
<< (mRegionp ? mRegionp->getRegionID() : LLUUID::null)
|
||||
<< LL_ENDL;
|
||||
if (mRegionp)
|
||||
{
|
||||
// We've changed regions, we're now going to change our agent coordinate frame.
|
||||
|
|
@ -2629,6 +2653,7 @@ void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
|
|||
else
|
||||
{
|
||||
mMaturityPreferenceNumRetries = 0;
|
||||
LL_WARNS() << "Too many retries for maturity preference" << LL_ENDL;
|
||||
reportPreferredMaturityError();
|
||||
}
|
||||
}
|
||||
|
|
@ -2680,6 +2705,7 @@ void LLAgent::reportPreferredMaturityError()
|
|||
mIsMaturityRatingChangingDuringTeleport = false;
|
||||
if (hasPendingTeleportRequest())
|
||||
{
|
||||
LL_WARNS("Teleport") << "Teleport failing due to preferred maturity error" << LL_ENDL;
|
||||
setTeleportState(LLAgent::TELEPORT_NONE);
|
||||
}
|
||||
|
||||
|
|
@ -3775,7 +3801,7 @@ void LLAgent::clearVisualParams(void *data)
|
|||
// protected
|
||||
bool LLAgent::teleportCore(bool is_local)
|
||||
{
|
||||
LL_INFOS("Teleport") << "In teleport core!" << LL_ENDL;
|
||||
LL_DEBUGS("Teleport") << "In teleport core" << LL_ENDL;
|
||||
if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
|
||||
{
|
||||
LL_WARNS() << "Attempt to teleport when already teleporting." << LL_ENDL;
|
||||
|
|
@ -3841,11 +3867,13 @@ bool LLAgent::teleportCore(bool is_local)
|
|||
add(LLStatViewer::TELEPORT, 1);
|
||||
if (is_local)
|
||||
{
|
||||
LL_INFOS("Teleport") << "Setting teleport state to TELEPORT_LOCAL" << LL_ENDL;
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
gTeleportDisplay = TRUE;
|
||||
LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_START );
|
||||
|
||||
//release geometry from old location
|
||||
|
|
@ -3912,6 +3940,7 @@ void LLAgent::startTeleportRequest()
|
|||
if (!isMaturityPreferenceSyncedWithServer())
|
||||
{
|
||||
gTeleportDisplay = TRUE;
|
||||
LL_INFOS("Teleport") << "Maturity preference not synced yet, setting teleport state to TELEPORT_PENDING" << LL_ENDL;
|
||||
setTeleportState(TELEPORT_PENDING);
|
||||
}
|
||||
else
|
||||
|
|
@ -3955,10 +3984,19 @@ void LLAgent::handleTeleportFinished()
|
|||
{
|
||||
if (mRegionp->capabilitiesReceived())
|
||||
{
|
||||
LL_DEBUGS("Teleport") << "capabilities have been received for region handle "
|
||||
<< mRegionp->getHandle()
|
||||
<< " id " << mRegionp->getRegionID()
|
||||
<< ", calling onCapabilitiesReceivedAfterTeleport()"
|
||||
<< LL_ENDL;
|
||||
onCapabilitiesReceivedAfterTeleport();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Teleport") << "Capabilities not yet received for region handle "
|
||||
<< mRegionp->getHandle()
|
||||
<< " id " << mRegionp->getRegionID()
|
||||
<< LL_ENDL;
|
||||
mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
|
||||
}
|
||||
}
|
||||
|
|
@ -3996,6 +4034,18 @@ void LLAgent::handleTeleportFailed()
|
|||
/*static*/
|
||||
void LLAgent::onCapabilitiesReceivedAfterTeleport()
|
||||
{
|
||||
if (gAgent.getRegion())
|
||||
{
|
||||
LL_DEBUGS("Teleport") << "running after capabilities received callback has been triggered, agent region "
|
||||
<< gAgent.getRegion()->getHandle()
|
||||
<< " id " << gAgent.getRegion()->getRegionID()
|
||||
<< " name " << gAgent.getRegion()->getName()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Teleport") << "called when agent region is null!" << LL_ENDL;
|
||||
}
|
||||
|
||||
check_merchant_status();
|
||||
}
|
||||
|
|
@ -4009,8 +4059,8 @@ void LLAgent::teleportRequest(
|
|||
LLViewerRegion* regionp = getRegion();
|
||||
if (regionp && teleportCore(region_handle == regionp->getHandle()))
|
||||
{
|
||||
LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':"
|
||||
<< pos_local << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "Sending TeleportLocationRequest: '" << region_handle << "':"
|
||||
<< pos_local << LL_ENDL;
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("TeleportLocationRequest");
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
|
|
@ -4041,6 +4091,11 @@ void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
|
|||
LLViewerRegion *regionp = getRegion();
|
||||
if(regionp && teleportCore())
|
||||
{
|
||||
LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
|
||||
<< " region id " << regionp->getRegionID()
|
||||
<< " requested landmark id " << landmark_asset_id
|
||||
<< LL_ENDL;
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
|
||||
msg->nextBlockFast(_PREHASH_Info);
|
||||
|
|
@ -4073,6 +4128,11 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
|
|||
teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
|
||||
}
|
||||
|
||||
LL_INFOS("Teleport") << "Sending TeleportLureRequest."
|
||||
<< " Current region handle " << regionp->getHandle()
|
||||
<< " region id " << regionp->getRegionID()
|
||||
<< " lure id " << lure_id
|
||||
<< LL_ENDL;
|
||||
// send the message
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_TeleportLureRequest);
|
||||
|
|
@ -4095,6 +4155,8 @@ void LLAgent::teleportCancel()
|
|||
LLViewerRegion* regionp = getRegion();
|
||||
if(regionp)
|
||||
{
|
||||
LL_INFOS("Teleport") << "Sending TeleportCancel" << LL_ENDL;
|
||||
|
||||
// send the message
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("TeleportCancel");
|
||||
|
|
@ -4107,13 +4169,14 @@ void LLAgent::teleportCancel()
|
|||
}
|
||||
clearTeleportRequest();
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
|
||||
gPipeline.resetVertexBuffers();
|
||||
gPipeline.resetVertexBuffers();
|
||||
}
|
||||
|
||||
void LLAgent::restoreCanceledTeleportRequest()
|
||||
{
|
||||
if (mTeleportCanceled != NULL)
|
||||
{
|
||||
LL_INFOS() << "Restoring canceled teleport request, setting state to TELEPORT_REQUESTED" << LL_ENDL;
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
|
||||
mTeleportRequest = mTeleportCanceled;
|
||||
mTeleportCanceled.reset();
|
||||
|
|
@ -4151,7 +4214,6 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
|
|||
else if(regionp &&
|
||||
teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
|
||||
{
|
||||
LL_WARNS() << "Using deprecated teleportlocationrequest." << LL_ENDL;
|
||||
// send the message
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_TeleportLocationRequest);
|
||||
|
|
@ -4171,6 +4233,14 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
|
|||
msg->addVector3Fast(_PREHASH_Position, pos);
|
||||
pos.mV[VX] += 1;
|
||||
msg->addVector3Fast(_PREHASH_LookAt, pos);
|
||||
|
||||
LL_WARNS("Teleport") << "Sending deprecated(?) TeleportLocationRequest."
|
||||
<< " pos_global " << pos_global
|
||||
<< " region_x " << region_x
|
||||
<< " region_y " << region_y
|
||||
<< " region_handle " << region_handle
|
||||
<< LL_ENDL;
|
||||
|
||||
sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
|
@ -4212,7 +4282,11 @@ void LLAgent::setTeleportState(ETeleportState state)
|
|||
" for previously failed teleport. Ignore!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS("Teleport") << "Setting teleport state to " << state << " Previous state: " << mTeleportState << LL_ENDL;
|
||||
LL_DEBUGS("Teleport") << "Setting teleport state to "
|
||||
<< LLAgent::teleportStateName(state) << "(" << state << ")"
|
||||
<< " Previous state: "
|
||||
<< teleportStateName(mTeleportState) << "(" << mTeleportState << ")"
|
||||
<< LL_ENDL;
|
||||
mTeleportState = state;
|
||||
if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
|
||||
{
|
||||
|
|
@ -4549,6 +4623,34 @@ void LLAgent::observeFriends()
|
|||
}
|
||||
}
|
||||
|
||||
std::map<S32, std::string> LLAgent::sTeleportStateName = { { TELEPORT_NONE, "TELEPORT_NONE" },
|
||||
{ TELEPORT_START, "TELEPORT_START" },
|
||||
{ TELEPORT_REQUESTED, "TELEPORT_REQUESTED" },
|
||||
{ TELEPORT_MOVING, "TELEPORT_MOVING" },
|
||||
{ TELEPORT_START_ARRIVAL, "TELEPORT_START_ARRIVAL" },
|
||||
{ TELEPORT_ARRIVING, "TELEPORT_ARRIVING" },
|
||||
{ TELEPORT_LOCAL, "TELEPORT_LOCAL" },
|
||||
{ TELEPORT_PENDING, "TELEPORT_PENDING" } };
|
||||
|
||||
const std::string& LLAgent::teleportStateName(S32 state)
|
||||
{
|
||||
static std::string invalid_state_str("INVALID");
|
||||
auto iter = LLAgent::sTeleportStateName.find(state);
|
||||
if (iter != LLAgent::sTeleportStateName.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return invalid_state_str;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& LLAgent::getTeleportStateName() const
|
||||
{
|
||||
return teleportStateName(getTeleportState());
|
||||
}
|
||||
|
||||
void LLAgent::parseTeleportMessages(const std::string& xml_filename)
|
||||
{
|
||||
LLXMLNodePtr root;
|
||||
|
|
@ -4672,40 +4774,70 @@ void LLTeleportRequest::restartTeleport()
|
|||
llassert(0);
|
||||
}
|
||||
|
||||
// TODO this enum -> name idiom should be in a common class rather than repeated various places.
|
||||
const std::string& LLTeleportRequest::statusName(EStatus status)
|
||||
{
|
||||
static std::string invalid_status_str("INVALID");
|
||||
auto iter = LLTeleportRequest::sTeleportStatusName.find(status);
|
||||
if (iter != LLTeleportRequest::sTeleportStatusName.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return invalid_status_str;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const LLTeleportRequest& req)
|
||||
{
|
||||
req.toOstream(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
void LLTeleportRequest::toOstream(std::ostream& os) const
|
||||
{
|
||||
os << "status " << statusName(mStatus) << "(" << mStatus << ")";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTeleportRequestViaLandmark
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
|
||||
: LLTeleportRequest(),
|
||||
mLandmarkId(pLandmarkId)
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created." << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
|
||||
}
|
||||
|
||||
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
|
||||
{
|
||||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark" << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
|
||||
{
|
||||
os << "landmark " << mLandmarkId << " ";
|
||||
LLTeleportRequest::toOstream(os);
|
||||
}
|
||||
|
||||
bool LLTeleportRequestViaLandmark::canRestartTeleport()
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true" << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true, " << *this << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLandmark::startTeleport()
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport" << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport, " << *this << LL_ENDL;
|
||||
gAgent.doTeleportViaLandmark(getLandmarkId());
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLandmark::restartTeleport()
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport" << LL_ENDL;
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport, " << *this << LL_ENDL;
|
||||
gAgent.doTeleportViaLandmark(getLandmarkId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTeleportRequestViaLure
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -4722,6 +4854,12 @@ LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
|
|||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLure" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
|
||||
{
|
||||
os << "mIsLureGodLike " << (S32) mIsLureGodLike << " ";
|
||||
LLTeleportRequestViaLandmark::toOstream(os);
|
||||
}
|
||||
|
||||
bool LLTeleportRequestViaLure::canRestartTeleport()
|
||||
{
|
||||
// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
|
||||
|
|
@ -4762,6 +4900,12 @@ LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
|
|||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLocation" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLocation::toOstream(std::ostream& os) const
|
||||
{
|
||||
os << "mPosGlobal " << mPosGlobal << " ";
|
||||
LLTeleportRequest::toOstream(os);
|
||||
}
|
||||
|
||||
bool LLTeleportRequestViaLocation::canRestartTeleport()
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLocation::canRestartTeleport -> true" << LL_ENDL;
|
||||
|
|
@ -4795,6 +4939,11 @@ LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
|
|||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLocationLookAt" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLTeleportRequestViaLocationLookAt::toOstream(std::ostream& os) const
|
||||
{
|
||||
LLTeleportRequestViaLocation::toOstream(os);
|
||||
}
|
||||
|
||||
bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
|
||||
{
|
||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLocationLookAt::canRestartTeleport -> true" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -47,20 +47,15 @@ extern const BOOL ANIMATE;
|
|||
extern const U8 AGENT_STATE_TYPING; // Typing indication
|
||||
extern const U8 AGENT_STATE_EDITING; // Set when agent has objects selected
|
||||
|
||||
class LLChat;
|
||||
class LLViewerRegion;
|
||||
class LLMotion;
|
||||
class LLToolset;
|
||||
class LLMessageSystem;
|
||||
class LLPermissions;
|
||||
class LLHost;
|
||||
class LLFriendObserver;
|
||||
class LLPickInfo;
|
||||
class LLViewerObject;
|
||||
class LLAgentDropGroupViewerNode;
|
||||
class LLAgentAccess;
|
||||
class LLSLURL;
|
||||
class LLPauseRequestHandle;
|
||||
class LLUIColor;
|
||||
class LLTeleportRequest;
|
||||
|
||||
|
|
@ -91,8 +86,6 @@ struct LLGroupData
|
|||
|
||||
class LLAgentListener;
|
||||
|
||||
class LLAgentImpl;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// LLAgent
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -619,6 +612,10 @@ public:
|
|||
TELEPORT_PENDING = 7
|
||||
};
|
||||
|
||||
static std::map<S32, std::string> sTeleportStateName;
|
||||
static const std::string& teleportStateName(S32);
|
||||
const std::string& getTeleportStateName() const;
|
||||
|
||||
public:
|
||||
static void parseTeleportMessages(const std::string& xml_filename);
|
||||
const void getTeleportSourceSLURL(LLSLURL& slurl) const;
|
||||
|
|
|
|||
|
|
@ -881,13 +881,6 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
|
|||
|
||||
void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index)
|
||||
{
|
||||
if (gAgent.isTeen() &&
|
||||
(type == LLWearableType::WT_UNDERSHIRT || type == LLWearableType::WT_UNDERPANTS))
|
||||
{
|
||||
// Can't take off underclothing in simple UI mode or on PG accounts
|
||||
// TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx
|
||||
return;
|
||||
}
|
||||
if (getWearableCount(type) == 0)
|
||||
{
|
||||
// no wearables to remove
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
|
||||
const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
|
||||
|
||||
std::list<AISAPI::ais_query_item_t> AISAPI::sPostponedQuery;
|
||||
|
||||
const S32 MAX_SIMULTANEOUS_COROUTINES = 2048;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*static*/
|
||||
bool AISAPI::isAvailable()
|
||||
|
|
@ -366,9 +370,51 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t
|
|||
/*static*/
|
||||
void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc)
|
||||
{
|
||||
LLCoprocedureManager &inst = LLCoprocedureManager::instance();
|
||||
S32 pending_in_pool = inst.countPending("AIS");
|
||||
std::string procFullName = "AIS(" + procName + ")";
|
||||
LLCoprocedureManager::instance().enqueueCoprocedure("AIS", procFullName, proc);
|
||||
if (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES)
|
||||
{
|
||||
inst.enqueueCoprocedure("AIS", procFullName, proc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// As I understand it, coroutines have built-in 'pending' pool
|
||||
// but unfortunately it has limited size which inventory often goes over
|
||||
// so this is a workaround to not overfill it.
|
||||
if (sPostponedQuery.empty())
|
||||
{
|
||||
sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
|
||||
gIdleCallbacks.addFunction(onIdle, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void AISAPI::onIdle(void *userdata)
|
||||
{
|
||||
if (!sPostponedQuery.empty())
|
||||
{
|
||||
LLCoprocedureManager &inst = LLCoprocedureManager::instance();
|
||||
S32 pending_in_pool = inst.countPending("AIS");
|
||||
while (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES && !sPostponedQuery.empty())
|
||||
{
|
||||
ais_query_item_t &item = sPostponedQuery.front();
|
||||
inst.enqueueCoprocedure("AIS", item.first, item.second);
|
||||
sPostponedQuery.pop_front();
|
||||
pending_in_pool++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sPostponedQuery.empty())
|
||||
{
|
||||
// Nothing to do anymore
|
||||
gIdleCallbacks.deleteFunction(onIdle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "llhttpretrypolicy.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llcorehttputil.h"
|
||||
#include "llcoproceduremanager.h"
|
||||
|
|
@ -72,6 +71,7 @@ private:
|
|||
const std::string, LLSD, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) > invokationFn_t;
|
||||
|
||||
static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc);
|
||||
static void onIdle(void *userdata); // launches postponed AIS commands
|
||||
|
||||
static std::string getInvCap();
|
||||
static std::string getLibCap();
|
||||
|
|
@ -80,6 +80,8 @@ private:
|
|||
invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body,
|
||||
completion_t callback, COMMAND_TYPE type);
|
||||
|
||||
typedef std::pair<std::string, LLCoprocedureManager::CoProcedure_t> ais_query_item_t;
|
||||
static std::list<ais_query_item_t> sPostponedQuery;
|
||||
};
|
||||
|
||||
class AISUpdate
|
||||
|
|
|
|||
|
|
@ -3278,6 +3278,50 @@ void update_base_outfit_after_ordering()
|
|||
bool copy_folder_links = false;
|
||||
app_mgr.slamCategoryLinks(app_mgr.getCOF(), base_outfit_id, copy_folder_links, dirty_state_updater);
|
||||
|
||||
if (base_outfit_id.notNull())
|
||||
{
|
||||
LLIsValidItemLink collector;
|
||||
|
||||
LLInventoryModel::cat_array_t cof_cats;
|
||||
LLInventoryModel::item_array_t cof_item_array;
|
||||
gInventory.collectDescendentsIf(app_mgr.getCOF(), cof_cats, cof_item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH, collector);
|
||||
|
||||
for (U32 i = 0; i < outfit_item_array.size(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem* linked_item = outfit_item_array.at(i)->getLinkedItem();
|
||||
if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
|
||||
{
|
||||
outfit_item_array.erase(outfit_item_array.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outfit_item_array.size() != cof_item_array.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::sort(cof_item_array.begin(), cof_item_array.end(), sort_by_linked_uuid);
|
||||
std::sort(outfit_item_array.begin(), outfit_item_array.end(), sort_by_linked_uuid);
|
||||
|
||||
for (U32 i = 0; i < cof_item_array.size(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem *cof_it = cof_item_array.at(i);
|
||||
LLViewerInventoryItem *base_it = outfit_item_array.at(i);
|
||||
|
||||
if (cof_it->getActualDescription() != base_it->getActualDescription())
|
||||
{
|
||||
if (cof_it->getLinkedUUID() == base_it->getLinkedUUID())
|
||||
{
|
||||
base_it->setDescription(cof_it->getActualDescription());
|
||||
gInventory.updateItem(base_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
LLAppearanceMgr::getInstance()->updateIsDirty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Save COF changes - update the contents of the current base outfit
|
||||
|
|
|
|||
|
|
@ -527,7 +527,8 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
|
|||
|
||||
LLIconCtrl* icon;
|
||||
|
||||
if(gAgent.isInGroup(match_id, TRUE))
|
||||
if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor
|
||||
|| gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group
|
||||
{
|
||||
LLGroupIconCtrl::Params icon_params;
|
||||
icon_params.group_id = match_id;
|
||||
|
|
@ -605,8 +606,9 @@ static void settings_to_globals()
|
|||
static void settings_modify()
|
||||
{
|
||||
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
|
||||
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
|
||||
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
||||
LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
|
||||
LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
|
||||
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
|
||||
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
|
||||
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
|
||||
|
|
@ -781,7 +783,7 @@ bool LLAppViewer::init()
|
|||
|
||||
// initialize the LLSettingsType translation bridge.
|
||||
LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();
|
||||
LLSettingsType::initClass(trans);
|
||||
LLSettingsType::initParamSingleton(trans);
|
||||
|
||||
// initialize SSE options
|
||||
LLVector4a::initClass();
|
||||
|
|
@ -1024,13 +1026,27 @@ bool LLAppViewer::init()
|
|||
{
|
||||
// can't use an alert here since we're exiting and
|
||||
// all hell breaks lose.
|
||||
LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements");
|
||||
OSMessageBox(
|
||||
LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
|
||||
details.getString(),
|
||||
LLStringUtil::null,
|
||||
OSMB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If we don't have the right shader requirements.
|
||||
if (!gGLManager.mHasShaderObjects
|
||||
|| !gGLManager.mHasVertexShader
|
||||
|| !gGLManager.mHasFragmentShader)
|
||||
{
|
||||
LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements");
|
||||
OSMessageBox(
|
||||
details.getString(),
|
||||
LLStringUtil::null,
|
||||
OSMB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Without SSE2 support we will crash almost immediately, warn here.
|
||||
if (!gSysCPU.hasSSE2())
|
||||
{
|
||||
|
|
@ -1501,8 +1517,10 @@ bool LLAppViewer::doFrame()
|
|||
}
|
||||
|
||||
// yield cooperatively when not running as foreground window
|
||||
if ( (gViewerWindow && !gViewerWindow->getWindow()->getVisible())
|
||||
|| !gFocusMgr.getAppHasFocus())
|
||||
// and when not quiting (causes trouble at mac's cleanup stage)
|
||||
if (!LLApp::isExiting()
|
||||
&& ((gViewerWindow && !gViewerWindow->getWindow()->getVisible())
|
||||
|| !gFocusMgr.getAppHasFocus()))
|
||||
{
|
||||
// Sleep if we're not rendering, or the window is minimized.
|
||||
static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40);
|
||||
|
|
@ -2100,8 +2118,6 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
LLError::LLCallStacks::cleanup();
|
||||
|
||||
removeMarkerFiles();
|
||||
|
||||
// It's not at first obvious where, in this long sequence, a generic cleanup
|
||||
// call OUGHT to go. So let's say this: as we migrate cleanup from
|
||||
// explicit hand-placed calls into the generic mechanism, eventually
|
||||
|
|
@ -2109,14 +2125,12 @@ bool LLAppViewer::cleanup()
|
|||
// still see above are calls that MUST happen before the generic cleanup
|
||||
// kicks in.
|
||||
|
||||
// The logging subsystem depends on an LLSingleton. Any logging after
|
||||
// LLSingletonBase::deleteAll() won't be recorded.
|
||||
LL_INFOS() << "Goodbye!" << LL_ENDL;
|
||||
|
||||
// This calls every remaining LLSingleton's cleanupSingleton() and
|
||||
// deleteSingleton() methods.
|
||||
LLSingletonBase::deleteAll();
|
||||
|
||||
LL_INFOS() << "Goodbye!" << LL_ENDL;
|
||||
|
||||
removeDumpDir();
|
||||
|
||||
// return 0;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
|
||||
#include "llsingleton.h"
|
||||
|
||||
class LLViewerInventoryItem;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LLAttachmentsMgr
|
||||
//
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include "lliconctrl.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llviewermenu.h"
|
||||
|
||||
class LLAvatarName;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include <boost/signals2.hpp>
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lloutputmonitorctrl.h"
|
||||
#include "llbutton.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llstyle.h"
|
||||
|
|
@ -38,6 +37,7 @@
|
|||
#include "llcallingcard.h" // for LLFriendObserver
|
||||
|
||||
class LLAvatarIconCtrl;
|
||||
class LLOutputMonitorCtrl;
|
||||
class LLAvatarName;
|
||||
class LLIconCtrl;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "llmultigesture.h"
|
||||
#include "llui.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include "llstring.h"
|
||||
#include "llurlaction.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llchatitemscontainerctrl.h"
|
||||
#include "llchatmsgbox.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
#include "llavataractions.h"
|
||||
|
|
|
|||
|
|
@ -28,12 +28,13 @@
|
|||
#define LL_LLCHATITEMSCONTAINERCTRL_H_
|
||||
|
||||
#include "llchat.h"
|
||||
#include "llchatmsgbox.h"
|
||||
#include "llpanel.h"
|
||||
#include "llscrollbar.h"
|
||||
#include "llviewerchat.h"
|
||||
#include "lltoastpanel.h"
|
||||
|
||||
class LLChatMsgBox;
|
||||
|
||||
typedef enum e_show_item_header
|
||||
{
|
||||
CHATITEMHEADER_SHOW_ONLY_NAME = 0,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llsingleton.h"
|
||||
#include "llsyswellwindow.h"
|
||||
#include "llfloaternotificationstabbed.h"
|
||||
#include "llviewermenu.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
|
||||
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
|
||||
|
|
|
|||
|
|
@ -140,10 +140,31 @@ protected:
|
|||
{
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
|
||||
registrar.add("Attachment.Touch", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
|
||||
registrar.add("Attachment.Edit", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
|
||||
registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
|
||||
|
||||
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
|
||||
enable_registrar.add("Attachment.OnEnable", boost::bind(&CofAttachmentContextMenu::onEnable, this, _2));
|
||||
|
||||
return createFromFile("menu_cof_attachment.xml");
|
||||
}
|
||||
|
||||
bool onEnable(const LLSD& userdata)
|
||||
{
|
||||
const std::string event_name = userdata.asString();
|
||||
|
||||
if ("touch" == event_name)
|
||||
{
|
||||
return (1 == mUUIDs.size()) && (enable_attachment_touch(mUUIDs.front()));
|
||||
}
|
||||
else if ("edit" == event_name)
|
||||
{
|
||||
return (1 == mUUIDs.size()) && (get_is_item_editable(mUUIDs.front()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
// Classes
|
||||
//
|
||||
class LLColor4;
|
||||
class LLFloaterColorPicker;
|
||||
|
||||
class LLColorSwatchCtrl
|
||||
: public LLUICtrl
|
||||
|
|
|
|||
|
|
@ -402,23 +402,30 @@ bool LLCommandLineParser::parseCommandLineString(const std::string& str)
|
|||
}
|
||||
}
|
||||
|
||||
// Split the string content into tokens
|
||||
const char* escape_chars = "\\";
|
||||
const char* separator_chars = "\r\n ";
|
||||
const char* quote_chars = "\"'";
|
||||
boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
|
||||
boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
|
||||
std::vector<std::string> tokens;
|
||||
// std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
|
||||
for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
|
||||
i != tok.end();
|
||||
++i)
|
||||
try
|
||||
{
|
||||
if(0 != i->size())
|
||||
// Split the string content into tokens
|
||||
const char* escape_chars = "\\";
|
||||
const char* separator_chars = "\r\n ";
|
||||
const char* quote_chars = "\"'";
|
||||
boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
|
||||
boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
|
||||
// std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
|
||||
for (boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
|
||||
i != tok.end();
|
||||
++i)
|
||||
{
|
||||
tokens.push_back(*i);
|
||||
if (0 != i->size())
|
||||
{
|
||||
tokens.push_back(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("Unexpected crash while parsing: " << str));
|
||||
}
|
||||
|
||||
po::command_line_parser clp(tokens);
|
||||
return parseAndStoreResults(clp);
|
||||
|
|
|
|||
|
|
@ -29,14 +29,11 @@
|
|||
|
||||
#include "llinventory.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llvoinventorylistener.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
#include "llevents.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -92,6 +92,23 @@ LLConversationItem::~LLConversationItem()
|
|||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLConversationItem::addChild(LLFolderViewModelItem* child)
|
||||
{
|
||||
// Avoid duplicates: bail out if that child is already present in the list
|
||||
// Note: this happens when models are created and 'parented' before views
|
||||
// This is performance unfriendly, but conversation can addToFolder multiple times
|
||||
child_list_t::const_iterator iter;
|
||||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
if (child == *iter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
LLFolderViewModelItemCommon::addChild(child);
|
||||
}
|
||||
|
||||
void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
|
||||
{
|
||||
LLUUID session_id = (session ? session->getUUID() : LLUUID());
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ public:
|
|||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
|
||||
virtual BOOL isUpToDate() const { return TRUE; }
|
||||
virtual bool hasChildren() const { return FALSE; }
|
||||
virtual void addChild(LLFolderViewModelItem* child);
|
||||
|
||||
virtual bool potentiallyVisible() { return true; }
|
||||
virtual bool filter( LLFolderViewFilter& filter) { return false; }
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ void LLConversationViewSession::refresh()
|
|||
// Refresh the session view from its model data
|
||||
LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
|
||||
vmi->resetRefresh();
|
||||
|
||||
|
||||
if (mSessionTitle)
|
||||
{
|
||||
mSessionTitle->setText(vmi->getDisplayName());
|
||||
|
|
@ -545,7 +545,9 @@ BOOL LLConversationViewParticipant::postBuild()
|
|||
}
|
||||
|
||||
updateChildren();
|
||||
return LLFolderViewItem::postBuild();
|
||||
LLFolderViewItem::postBuild();
|
||||
refresh();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLConversationViewParticipant::draw()
|
||||
|
|
@ -619,7 +621,7 @@ void LLConversationViewParticipant::refresh()
|
|||
|
||||
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
|
||||
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
|
||||
|
||||
|
||||
// Do the regular upstream refresh
|
||||
LLFolderViewItem::refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "lloutputmonitorctrl.h"
|
||||
|
||||
class LLTextBox;
|
||||
class LLFloater;
|
||||
class LLFloaterIMContainer;
|
||||
class LLConversationViewSession;
|
||||
class LLConversationViewParticipant;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include "lldrawable.h"
|
||||
#include "lldrawpoolbump.h"
|
||||
#include "llface.h"
|
||||
#include "llvolume.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llsky.h"
|
||||
#include "llviewercamera.h"
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ void LLDrawPoolWater::render(S32 pass)
|
|||
std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
|
||||
|
||||
// See if we are rendering water as opaque or not
|
||||
if (!gSavedSettings.getBOOL("RenderTransparentWater"))
|
||||
if (!LLPipeline::sRenderTransparentWater)
|
||||
{
|
||||
// render water for low end hardware
|
||||
renderOpaqueLegacyWater();
|
||||
|
|
|
|||
|
|
@ -806,6 +806,25 @@ const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
|
|||
const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01);
|
||||
const U32 LLEnvironment::DayInstance::NO_ANIMATE_WATER(0x02);
|
||||
|
||||
std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel)
|
||||
{
|
||||
#define RTNENUM(E) case LLEnvironment::E: return #E
|
||||
switch (sel){
|
||||
RTNENUM(ENV_EDIT);
|
||||
RTNENUM(ENV_LOCAL);
|
||||
RTNENUM(ENV_PUSH);
|
||||
RTNENUM(ENV_PARCEL);
|
||||
RTNENUM(ENV_REGION);
|
||||
RTNENUM(ENV_DEFAULT);
|
||||
RTNENUM(ENV_END);
|
||||
RTNENUM(ENV_CURRENT);
|
||||
RTNENUM(ENV_NONE);
|
||||
default:
|
||||
return llformat("Unknown(%d)", sel);
|
||||
}
|
||||
#undef RTNENUM
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
LLEnvironment::LLEnvironment():
|
||||
|
|
@ -981,7 +1000,7 @@ bool LLEnvironment::canAgentUpdateRegionEnvironment() const
|
|||
if (gAgent.isGodlike())
|
||||
return true;
|
||||
|
||||
return gAgent.getRegion()->canManageEstate();
|
||||
return gAgent.canManageEstate();
|
||||
}
|
||||
|
||||
bool LLEnvironment::isExtendedEnvironmentEnabled() const
|
||||
|
|
@ -1037,7 +1056,8 @@ F32 LLEnvironment::getCamHeight() const
|
|||
|
||||
F32 LLEnvironment::getWaterHeight() const
|
||||
{
|
||||
return gAgent.getRegion()->getWaterHeight();
|
||||
LLViewerRegion* cur_region = gAgent.getRegion();
|
||||
return cur_region ? cur_region->getWaterHeight() : DEFAULT_WATER_HEIGHT;
|
||||
}
|
||||
|
||||
bool LLEnvironment::getIsSunUp() const
|
||||
|
|
@ -1059,6 +1079,7 @@ void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LL
|
|||
{
|
||||
mSelectedEnvironment = env;
|
||||
updateEnvironment(transition, forced);
|
||||
LL_DEBUGS("ENVIRONMENT") << "Setting environment " << env_selection_to_string(env) << " with transition: " << transition << LL_ENDL;
|
||||
}
|
||||
|
||||
bool LLEnvironment::hasEnvironment(LLEnvironment::EnvSelection_t env)
|
||||
|
|
@ -1095,11 +1116,13 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnviro
|
|||
void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)
|
||||
{
|
||||
if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
logEnvironment(env, pday, env_version);
|
||||
|
||||
DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
|
||||
|
||||
environment->clear();
|
||||
|
|
@ -1116,7 +1139,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
|
|||
{
|
||||
if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1125,30 +1148,32 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
|
|||
|
||||
if (fixed.first)
|
||||
{
|
||||
logEnvironment(env, fixed.first, env_version);
|
||||
environment->setSky(fixed.first);
|
||||
environment->setFlags(DayInstance::NO_ANIMATE_SKY);
|
||||
}
|
||||
else if (!environment->getSky())
|
||||
{
|
||||
LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL;
|
||||
environment->setSky(mCurrentEnvironment->getSky());
|
||||
environment->setFlags(DayInstance::NO_ANIMATE_SKY);
|
||||
}
|
||||
|
||||
if (fixed.second)
|
||||
{
|
||||
logEnvironment(env, fixed.second, env_version);
|
||||
environment->setWater(fixed.second);
|
||||
environment->setFlags(DayInstance::NO_ANIMATE_WATER);
|
||||
}
|
||||
else if (!environment->getWater())
|
||||
{
|
||||
LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL;
|
||||
environment->setWater(mCurrentEnvironment->getWater());
|
||||
environment->setFlags(DayInstance::NO_ANIMATE_WATER);
|
||||
}
|
||||
|
||||
if (!mSignalEnvChanged.empty())
|
||||
mSignalEnvChanged(env, env_version);
|
||||
|
||||
/*TODO: readjust environment*/
|
||||
}
|
||||
|
||||
void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
|
||||
|
|
@ -1221,10 +1246,12 @@ void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
|
|||
if (!settings || status)
|
||||
{
|
||||
LLSD args;
|
||||
args["DESC"] = asset_id.asString();
|
||||
args["NAME"] = asset_id.asString();
|
||||
LLNotificationsUtil::add("FailedToFindSettings", args);
|
||||
LL_DEBUGS("ENVIRONMENT") << "Failed to find settings for " << env_selection_to_string(env) << ", asset_id: " << asset_id << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS("ENVIRONMENT") << "Loaded asset: " << asset_id << LL_ENDL;
|
||||
|
||||
setEnvironment(env, settings);
|
||||
updateEnvironment(transition);
|
||||
|
|
@ -1238,19 +1265,48 @@ void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)
|
|||
return;
|
||||
}
|
||||
|
||||
LL_DEBUGS("ENVIRONMENT") << "Cleaning environment " << env_selection_to_string(env) << LL_ENDL;
|
||||
|
||||
mEnvironments[env].reset();
|
||||
|
||||
if (!mSignalEnvChanged.empty())
|
||||
mSignalEnvChanged(env, VERSION_CLEANUP);
|
||||
}
|
||||
|
||||
/*TODO: readjust environment*/
|
||||
void LLEnvironment::logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
|
||||
{
|
||||
LL_DEBUGS("ENVIRONMENT") << "Setting Day environment " << env_selection_to_string(env) << " with version(update type): " << env_version << LL_NEWLINE;
|
||||
// code between LL_DEBUGS and LL_ENDL won't execute unless log is enabled
|
||||
if (settings)
|
||||
{
|
||||
LLUUID asset_id = settings->getAssetId();
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
LL_CONT << "Asset id: " << asset_id << LL_NEWLINE;
|
||||
}
|
||||
|
||||
LLUUID id = settings->getId(); // Not in use?
|
||||
if (id.notNull())
|
||||
{
|
||||
LL_CONT << "Settings id: " << id << LL_NEWLINE;
|
||||
}
|
||||
|
||||
LL_CONT << "Name: " << settings->getName() << LL_NEWLINE
|
||||
<< "Type: " << settings->getSettingsType() << LL_NEWLINE
|
||||
<< "Flags: " << settings->getFlags(); // Not in use?
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_CONT << "Empty settings!";
|
||||
}
|
||||
LL_CONT << LL_ENDL;
|
||||
}
|
||||
|
||||
LLSettingsDay::ptr_t LLEnvironment::getEnvironmentDay(LLEnvironment::EnvSelection_t env)
|
||||
{
|
||||
if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return LLSettingsDay::ptr_t();
|
||||
}
|
||||
|
||||
|
|
@ -1266,7 +1322,7 @@ LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayLength(EnvSelection_t env
|
|||
{
|
||||
if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return LLSettingsDay::Seconds(0);
|
||||
}
|
||||
|
||||
|
|
@ -1282,7 +1338,7 @@ LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayOffset(EnvSelection_t env
|
|||
{
|
||||
if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return LLSettingsDay::Seconds(0);
|
||||
}
|
||||
|
||||
|
|
@ -1325,7 +1381,7 @@ LLEnvironment::fixedEnvironment_t LLEnvironment::getEnvironmentFixed(LLEnvironme
|
|||
|
||||
if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
|
||||
{
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
|
||||
LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
|
||||
return fixedEnvironment_t();
|
||||
}
|
||||
|
||||
|
|
@ -2361,7 +2417,7 @@ void LLEnvironment::onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettin
|
|||
if (!settings || status)
|
||||
{
|
||||
LLSD args;
|
||||
args["DESC"] = experience_id.asString();
|
||||
args["NAME"] = experience_id.asString();
|
||||
LLNotificationsUtil::add("FailedToFindSettings", args);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3332,7 +3388,7 @@ namespace
|
|||
return;
|
||||
}
|
||||
|
||||
LL_WARNS("PUSHENV") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
|
||||
LL_WARNS("PUSHENV", "ENVIRONMENT") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
|
||||
|
||||
LLEnvironment::DayInstance::ptr_t trans = std::make_shared<InjectedTransition>(std::static_pointer_cast<DayInjection>(shared_from_this()),
|
||||
mBaseDayInstance->getSky(), mBaseDayInstance->getWater(), nextbase, LLEnvironment::TRANSITION_DEFAULT);
|
||||
|
|
|
|||
|
|
@ -148,8 +148,11 @@ public:
|
|||
void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
|
||||
|
||||
void setSharedEnvironment();
|
||||
|
||||
void clearEnvironment(EnvSelection_t env);
|
||||
|
||||
static void logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version = NO_VERSION);
|
||||
|
||||
|
||||
LLSettingsDay::ptr_t getEnvironmentDay(EnvSelection_t env);
|
||||
LLSettingsDay::Seconds getEnvironmentDayLength(EnvSelection_t env);
|
||||
LLSettingsDay::Seconds getEnvironmentDayOffset(EnvSelection_t env);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ BOOL LLFloaterConversationPreview::postBuild()
|
|||
file = "chat";
|
||||
}
|
||||
mChatHistoryFileName = file;
|
||||
|
||||
if (mIsGroup && !LLStringUtil::endsWith(mChatHistoryFileName, GROUP_CHAT_SUFFIX))
|
||||
{
|
||||
mChatHistoryFileName += GROUP_CHAT_SUFFIX;
|
||||
}
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[NAME]"] = name;
|
||||
std::string title = getString("Title", args);
|
||||
|
|
|
|||
|
|
@ -1498,7 +1498,7 @@ void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::pt
|
|||
if (!settings || status)
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
|
||||
args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
|
||||
LLNotificationsUtil::add("FailedToFindSettings", args);
|
||||
closeFloater();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::p
|
|||
if (!settings || status)
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
|
||||
args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
|
||||
LLNotificationsUtil::add("FailedToFindSettings", args);
|
||||
closeFloater();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "llcallbacklist.h"
|
||||
#include "llworld.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llviewermenu.h" // is_agent_mappable
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "boost/foreach.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -1322,9 +1322,11 @@ void LLFloaterPreference::refreshEnabledState()
|
|||
|
||||
//Deferred/SSAO/Shadows
|
||||
BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
|
||||
BOOL transparent_water = LLFeatureManager::getInstance()->isFeatureAvailable("RenderTransparentWater") && gSavedSettings.getBOOL("RenderTransparentWater");
|
||||
BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
|
||||
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
|
||||
bumpshiny &&
|
||||
transparent_water &&
|
||||
shaders &&
|
||||
gGLManager.mHasFramebufferObject &&
|
||||
gSavedSettings.getBOOL("RenderAvatarVP") &&
|
||||
|
|
@ -1347,7 +1349,10 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
|
|||
BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
|
||||
ctrl_reflections->setEnabled(reflections);
|
||||
reflections_text->setEnabled(reflections);
|
||||
|
||||
|
||||
// Transparent Water
|
||||
LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
|
||||
|
||||
// Bump & Shiny
|
||||
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
|
||||
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
|
||||
|
|
@ -1398,6 +1403,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
|
|||
|
||||
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
|
||||
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
|
||||
((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
|
||||
gGLManager.mHasFramebufferObject &&
|
||||
gSavedSettings.getBOOL("RenderAvatarVP") &&
|
||||
(ctrl_wind_light->get()) ? TRUE : FALSE;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
class LLSpinCtrl;
|
||||
class LLSnapshotLivePreview;
|
||||
class LLToolset;
|
||||
|
||||
class LLFloaterSnapshotBase : public LLFloater
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#define LL_LLFLOATERWORLDMAP_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llhudtext.h"
|
||||
#include "llmapimagetype.h"
|
||||
#include "lltracker.h"
|
||||
#include "llslurl.h"
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ protected:
|
|||
static void sortObjects();
|
||||
|
||||
LLHUDObject(const U8 type);
|
||||
~LLHUDObject();
|
||||
virtual ~LLHUDObject();
|
||||
|
||||
virtual void render() = 0;
|
||||
virtual void renderForTimer() {};
|
||||
|
|
|
|||
|
|
@ -565,7 +565,10 @@ S32 LLHUDText::getMaxLines()
|
|||
|
||||
void LLHUDText::markDead()
|
||||
{
|
||||
sTextObjects.erase(LLPointer<LLHUDText>(this));
|
||||
// make sure we have at least one pointer
|
||||
// till the end of the function
|
||||
LLPointer<LLHUDText> ptr(this);
|
||||
sTextObjects.erase(ptr);
|
||||
LLHUDObject::markDead();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6420,6 +6420,14 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
{
|
||||
LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, false); // Don't replace if adding.
|
||||
}
|
||||
else if ("touch" == action)
|
||||
{
|
||||
handle_attachment_touch(mUUID);
|
||||
}
|
||||
else if ("edit" == action)
|
||||
{
|
||||
handle_attachment_edit(mUUID);
|
||||
}
|
||||
else if (isRemoveAction(action))
|
||||
{
|
||||
LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
|
||||
|
|
@ -6570,6 +6578,19 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
if( get_is_item_worn( mUUID ) )
|
||||
{
|
||||
items.push_back(std::string("Wearable And Object Separator"));
|
||||
|
||||
items.push_back(std::string("Attachment Touch"));
|
||||
if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !enable_attachment_touch(mUUID) )
|
||||
{
|
||||
disabled_items.push_back(std::string("Attachment Touch"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("Wearable Edit"));
|
||||
if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !get_is_item_editable(mUUID) )
|
||||
{
|
||||
disabled_items.push_back(std::string("Wearable Edit"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("Detach From Yourself"));
|
||||
}
|
||||
else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing() && !isCOFFolder())
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
#include "lltooldraganddrop.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
|
|
@ -655,6 +656,50 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool get_is_item_editable(const LLUUID& inv_item_id)
|
||||
{
|
||||
if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
|
||||
{
|
||||
switch (inv_item->getType())
|
||||
{
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
return gAgentWearables.isWearableModifiable(inv_item_id);
|
||||
case LLAssetType::AT_OBJECT:
|
||||
return true;
|
||||
default:
|
||||
return false;;
|
||||
}
|
||||
}
|
||||
return gAgentAvatarp->getWornAttachment(inv_item_id) != nullptr;
|
||||
}
|
||||
|
||||
void handle_item_edit(const LLUUID& inv_item_id)
|
||||
{
|
||||
if (get_is_item_editable(inv_item_id))
|
||||
{
|
||||
if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
|
||||
{
|
||||
switch (inv_item->getType())
|
||||
{
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
LLAgentWearables::editWearable(inv_item_id);
|
||||
break;
|
||||
case LLAssetType::AT_OBJECT:
|
||||
handle_attachment_edit(inv_item_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_attachment_edit(inv_item_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
{
|
||||
// NOTE: This function doesn't check the folder's children.
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ BOOL get_can_item_be_worn(const LLUUID& id);
|
|||
|
||||
BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
// Performs the appropiate edit action (if one exists) for this item
|
||||
bool get_is_item_editable(const LLUUID& inv_item_id);
|
||||
void handle_item_edit(const LLUUID& inv_item_id);
|
||||
|
||||
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "llcallbacklist.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llgesturemgr.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include "bufferarray.h"
|
||||
#include "bufferstream.h"
|
||||
|
|
@ -76,8 +77,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
|
|||
///----------------------------------------------------------------------------
|
||||
|
||||
//BOOL decompress_file(const char* src_filename, const char* dst_filename);
|
||||
static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv";
|
||||
static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv";
|
||||
static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv.llsd";
|
||||
static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv.llsd";
|
||||
static const char * const LOG_INV("Inventory");
|
||||
|
||||
struct InventoryIDPtrLess
|
||||
|
|
@ -683,17 +684,59 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
|
|||
|
||||
LLUUID categoryId = result["folder_id"].asUUID();
|
||||
|
||||
// Add the category to the internal representation
|
||||
LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
|
||||
result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
|
||||
result["name"].asString(), gAgent.getID());
|
||||
LLViewerInventoryCategory* folderp = gInventory.getCategory(categoryId);
|
||||
if (!folderp)
|
||||
{
|
||||
// Add the category to the internal representation
|
||||
LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
|
||||
result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
|
||||
result["name"].asString(), gAgent.getID());
|
||||
|
||||
cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
|
||||
cat->setDescendentCount(0);
|
||||
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
|
||||
|
||||
accountForUpdate(update);
|
||||
updateCategory(cat);
|
||||
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
|
||||
accountForUpdate(update);
|
||||
|
||||
cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
|
||||
cat->setDescendentCount(0);
|
||||
updateCategory(cat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// bulk processing was faster than coroutine (coro request->processBulkUpdateInventory->coro response)
|
||||
// category already exists, but needs an update
|
||||
if (folderp->getVersion() != LLViewerInventoryCategory::VERSION_INITIAL
|
||||
|| folderp->getDescendentCount() != LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
|
||||
{
|
||||
LL_WARNS() << "Inventory desync on folder creation. Newly created folder already has descendants or got a version.\n"
|
||||
<< "Name: " << folderp->getName()
|
||||
<< " Id: " << folderp->getUUID()
|
||||
<< " Version: " << folderp->getVersion()
|
||||
<< " Descendants: " << folderp->getDescendentCount()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
// Recreate category with correct values
|
||||
// Creating it anew just simplifies figuring out needed change-masks
|
||||
// and making all needed updates, see updateCategory
|
||||
LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
|
||||
result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
|
||||
result["name"].asString(), gAgent.getID());
|
||||
|
||||
if (folderp->getParentUUID() != cat->getParentUUID())
|
||||
{
|
||||
LL_WARNS() << "Inventory desync on folder creation. Newly created folder has wrong parent.\n"
|
||||
<< "Name: " << folderp->getName()
|
||||
<< " Id: " << folderp->getUUID()
|
||||
<< " Expected parent: " << cat->getParentUUID()
|
||||
<< " Actual parent: " << folderp->getParentUUID()
|
||||
<< LL_ENDL;
|
||||
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
|
||||
accountForUpdate(update);
|
||||
}
|
||||
// else: Do not update parent, parent is already aware of the change. See processBulkUpdateInventory
|
||||
|
||||
cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
|
||||
cat->setDescendentCount(0);
|
||||
updateCategory(cat);
|
||||
}
|
||||
|
||||
if (callback)
|
||||
{
|
||||
|
|
@ -908,16 +951,29 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
|
|||
LLUUID new_parent_id = item->getParentUUID();
|
||||
bool update_parent_on_server = false;
|
||||
|
||||
if (new_parent_id.isNull())
|
||||
if (new_parent_id.isNull() && !LLApp::isExiting())
|
||||
{
|
||||
// item with null parent will end in random location and then in Lost&Found,
|
||||
// either move to default folder as if it is new item or don't move at all
|
||||
LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
|
||||
<< " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
|
||||
<< ". New name: " << item->getName()
|
||||
<< "." << LL_ENDL;
|
||||
new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
|
||||
update_parent_on_server = true;
|
||||
if (old_parent_id.isNull())
|
||||
{
|
||||
// Item with null parent will end in random location and then in Lost&Found,
|
||||
// either move to default folder as if it is new item or don't move at all
|
||||
LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
|
||||
<< " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
|
||||
<< ". New name: " << item->getName()
|
||||
<< "." << LL_ENDL;
|
||||
new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
|
||||
update_parent_on_server = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point
|
||||
LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
|
||||
<< " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName()
|
||||
<< ". New name: " << item->getName()
|
||||
<< "." << LL_ENDL;
|
||||
new_parent_id = old_parent_id;
|
||||
update_parent_on_server = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(old_parent_id != new_parent_id)
|
||||
|
|
@ -2653,29 +2709,37 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
|||
{
|
||||
if(filename.empty())
|
||||
{
|
||||
LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
|
||||
LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LL_INFOS(LOG_INV) << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL;
|
||||
LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
|
||||
if(!file)
|
||||
LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
|
||||
|
||||
llifstream file(filename.c_str());
|
||||
|
||||
if (!file.is_open())
|
||||
{
|
||||
LL_INFOS(LOG_INV) << "unable to load inventory from: " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
// *NOTE: This buffer size is hard coded into scanf() below.
|
||||
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
|
||||
char keyword[MAX_STRING]; /*Flawfinder: ignore*/
|
||||
char value[MAX_STRING]; /*Flawfinder: ignore*/
|
||||
is_cache_obsolete = true; // Obsolete until proven current
|
||||
while(!feof(file) && fgets(buffer, MAX_STRING, file))
|
||||
|
||||
is_cache_obsolete = true; // Obsolete until proven current
|
||||
|
||||
std::string line;
|
||||
LLPointer<LLSDParser> parser = new LLSDNotationParser();
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
sscanf(buffer, " %126s %126s", keyword, value); /* Flawfinder: ignore */
|
||||
if(0 == strcmp("inv_cache_version", keyword))
|
||||
LLSD s_item;
|
||||
std::istringstream iss(line);
|
||||
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
|
||||
{
|
||||
S32 version;
|
||||
int succ = sscanf(value,"%d",&version);
|
||||
if ((1 == succ) && (version == sCurrentInvCacheVersion))
|
||||
LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_item.has("inv_cache_version"))
|
||||
{
|
||||
S32 version = s_item["inv_cache_version"].asInteger();
|
||||
if (version == sCurrentInvCacheVersion)
|
||||
{
|
||||
// Cache is up to date
|
||||
is_cache_obsolete = false;
|
||||
|
|
@ -2683,43 +2747,33 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
|||
}
|
||||
else
|
||||
{
|
||||
// Cache is out of date
|
||||
LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("inv_category", keyword))
|
||||
else if (s_item.has("cat_id"))
|
||||
{
|
||||
if (is_cache_obsolete)
|
||||
break;
|
||||
|
||||
|
||||
LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
|
||||
if(inv_cat->importFileLocal(file))
|
||||
if(inv_cat->importLLSD(s_item))
|
||||
{
|
||||
categories.push_back(inv_cat);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL;
|
||||
//delete inv_cat; // automatic when inv_cat is reassigned or destroyed
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("inv_item", keyword))
|
||||
else if (s_item.has("item_id"))
|
||||
{
|
||||
if (is_cache_obsolete)
|
||||
break;
|
||||
|
||||
LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
|
||||
if( inv_item->importFileLocal(file) )
|
||||
if( inv_item->fromLLSD(s_item) )
|
||||
{
|
||||
// *FIX: Need a better solution, this prevents the
|
||||
// application from freezing, but breaks inventory
|
||||
// caching.
|
||||
if(inv_item->getUUID().isNull())
|
||||
{
|
||||
//delete inv_item; // automatic when inv_cat is reassigned or destroyed
|
||||
LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
|
||||
<< inv_item->getName() << LL_ENDL;
|
||||
|
||||
<< inv_item->getName() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2732,62 +2786,63 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
|||
items.push_back(inv_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL;
|
||||
//delete inv_item; // automatic when inv_cat is reassigned or destroyed
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Unknown token in inventory file '" << keyword << "'"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
if (is_cache_obsolete)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
file.close();
|
||||
|
||||
return !is_cache_obsolete;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLInventoryModel::saveToFile(const std::string& filename,
|
||||
const cat_array_t& categories,
|
||||
const item_array_t& items)
|
||||
const cat_array_t& categories,
|
||||
const item_array_t& items)
|
||||
{
|
||||
if(filename.empty())
|
||||
if (filename.empty())
|
||||
{
|
||||
LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LL_INFOS(LOG_INV) << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL;
|
||||
LLFILE* file = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
|
||||
if(!file)
|
||||
|
||||
LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL;
|
||||
|
||||
llofstream fileXML(filename.c_str());
|
||||
if (!fileXML.is_open())
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(file, "\tinv_cache_version\t%d\n",sCurrentInvCacheVersion);
|
||||
LLSD cache_ver;
|
||||
cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
|
||||
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
|
||||
|
||||
S32 count = categories.size();
|
||||
S32 cat_count = 0;
|
||||
S32 i;
|
||||
for(i = 0; i < count; ++i)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = categories[i];
|
||||
if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||
{
|
||||
cat->exportFileLocal(file);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
|
||||
cat_count++;
|
||||
}
|
||||
}
|
||||
|
||||
count = items.size();
|
||||
for(i = 0; i < count; ++i)
|
||||
S32 it_count = items.size();
|
||||
for(i = 0; i < it_count; ++i)
|
||||
{
|
||||
items[i]->exportFile(file);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
fileXML.close();
|
||||
|
||||
LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
|
|||
mCompletionObserver(NULL),
|
||||
mScroller(NULL),
|
||||
mSortOrderSetting(p.sort_order_setting),
|
||||
mInventory(p.inventory),
|
||||
mInventory(p.inventory), //inventory("", &gInventory)
|
||||
mAcceptsDragAndDrop(p.accepts_drag_and_drop),
|
||||
mAllowMultiSelect(p.allow_multi_select),
|
||||
mAllowDrag(p.allow_drag),
|
||||
|
|
@ -514,7 +514,18 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
|
|||
view_item->destroyView();
|
||||
removeItemID(idp);
|
||||
}
|
||||
view_item = buildNewViews(item_id);
|
||||
|
||||
LLInventoryObject const* objectp = mInventory->getObject(item_id);
|
||||
if (objectp)
|
||||
{
|
||||
// providing NULL directly avoids unnessesary getItemByID calls
|
||||
view_item = buildNewViews(item_id, objectp, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
view_item = NULL;
|
||||
}
|
||||
|
||||
viewmodel_item =
|
||||
static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
|
||||
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
|
||||
|
|
@ -557,7 +568,13 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
|
|||
if (model_item && !view_item)
|
||||
{
|
||||
// Add the UI element for this item.
|
||||
buildNewViews(item_id);
|
||||
LLInventoryObject const* objectp = mInventory->getObject(item_id);
|
||||
if (objectp)
|
||||
{
|
||||
// providing NULL directly avoids unnessesary getItemByID calls
|
||||
buildNewViews(item_id, objectp, NULL);
|
||||
}
|
||||
|
||||
// Select any newly created object that has the auto rename at top of folder root set.
|
||||
if(mFolderRoot.get()->getRoot()->needsAutoRename())
|
||||
{
|
||||
|
|
@ -854,7 +871,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
|
|||
|
||||
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
{
|
||||
LLInventoryObject const* objectp = gInventory.getObject(id);
|
||||
LLInventoryObject const* objectp = mInventory->getObject(id);
|
||||
return buildNewViews(id, objectp);
|
||||
}
|
||||
|
||||
|
|
@ -864,11 +881,43 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
LLFolderViewItem* folder_view_item = getItemByID(id);
|
||||
if (!typedViewsFilter(id, objectp))
|
||||
{
|
||||
// if certain types are not allowed permanently, no reason to create views
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
|
||||
|
||||
LLFolderViewItem* folder_view_item = getItemByID(id);
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
|
||||
|
||||
return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
|
||||
}
|
||||
|
||||
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *folder_view_item)
|
||||
{
|
||||
if (!objectp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!typedViewsFilter(id, objectp))
|
||||
{
|
||||
// if certain types are not allowed permanently, no reason to create views
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
|
||||
|
||||
return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
|
||||
}
|
||||
|
||||
LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
|
||||
const LLUUID& parent_id,
|
||||
LLInventoryObject const* objectp,
|
||||
LLFolderViewItem *folder_view_item,
|
||||
LLFolderViewFolder *parent_folder)
|
||||
{
|
||||
// Force the creation of an extra root level folder item if required by the inventory panel (default is "false")
|
||||
bool allow_drop = true;
|
||||
bool create_root = false;
|
||||
|
|
@ -889,7 +938,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
|
|||
{
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE)
|
||||
{
|
||||
LL_WARNS() << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
|
||||
LL_WARNS() << "LLInventoryPanel::buildViewsTree called with invalid objectp->mType : "
|
||||
<< ((S32)objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
|
||||
<< LL_ENDL;
|
||||
return NULL;
|
||||
|
|
@ -898,7 +947,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
|
|||
if (objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
// Example: Happens when we add assets of new, not yet supported type to library
|
||||
LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
|
||||
LL_DEBUGS() << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
|
||||
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
|
||||
<< LL_ENDL;
|
||||
|
||||
|
|
@ -975,26 +1024,52 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
|
|||
LLViewerInventoryCategory::cat_array_t* categories;
|
||||
LLViewerInventoryItem::item_array_t* items;
|
||||
mInventory->lockDirectDescendentArrays(id, categories, items);
|
||||
|
||||
|
||||
LLFolderViewFolder *parentp = dynamic_cast<LLFolderViewFolder*>(folder_view_item);
|
||||
|
||||
if(categories)
|
||||
{
|
||||
{
|
||||
bool has_folders = parentp->getFoldersCount() > 0;
|
||||
for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
|
||||
cat_iter != categories->end();
|
||||
++cat_iter)
|
||||
{
|
||||
const LLViewerInventoryCategory* cat = (*cat_iter);
|
||||
buildNewViews(cat->getUUID());
|
||||
if (typedViewsFilter(cat->getUUID(), cat))
|
||||
{
|
||||
if (has_folders)
|
||||
{
|
||||
// This can be optimized: we don't need to call getItemByID()
|
||||
// each time, especially since content is growing, we can just
|
||||
// iter over copy of mItemMap in some way
|
||||
LLFolderViewItem* view_itemp = getItemByID(cat->getUUID());
|
||||
buildViewsTree(cat->getUUID(), id, cat, view_itemp, parentp);
|
||||
}
|
||||
else
|
||||
{
|
||||
buildViewsTree(cat->getUUID(), id, cat, NULL, parentp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(items)
|
||||
{
|
||||
{
|
||||
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
|
||||
item_iter != items->end();
|
||||
++item_iter)
|
||||
{
|
||||
const LLViewerInventoryItem* item = (*item_iter);
|
||||
buildNewViews(item->getUUID());
|
||||
if (typedViewsFilter(item->getUUID(), item))
|
||||
{
|
||||
|
||||
// This can be optimized: we don't need to call getItemByID()
|
||||
// each time, especially since content is growing, we can just
|
||||
// iter over copy of mItemMap in some way
|
||||
LLFolderViewItem* view_itemp = getItemByID(item->getUUID());
|
||||
buildViewsTree(item->getUUID(), id, item, view_itemp, parentp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mInventory->unlockDirectDescendentArrays(id);
|
||||
|
|
@ -1911,21 +1986,20 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
|
|||
return result;
|
||||
}
|
||||
|
||||
LLFolderViewItem* LLAssetFilteredInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
/*virtual*/
|
||||
bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp)
|
||||
{
|
||||
LLInventoryObject const* objectp = gInventory.getObject(id);
|
||||
|
||||
if (!objectp)
|
||||
{
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
|
||||
{
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return LLInventoryPanel::buildNewViews(id, objectp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item)
|
||||
|
|
|
|||
|
|
@ -329,8 +329,15 @@ protected:
|
|||
static LLUIColor sLibraryColor;
|
||||
static LLUIColor sLinkColor;
|
||||
|
||||
virtual LLFolderViewItem* buildNewViews(const LLUUID& id);
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp);
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id);
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id,
|
||||
LLInventoryObject const* objectp);
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id,
|
||||
LLInventoryObject const* objectp,
|
||||
LLFolderViewItem *target_view);
|
||||
// if certain types are not allowed, no reason to create views
|
||||
virtual bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; }
|
||||
|
||||
virtual void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item);
|
||||
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
|
||||
|
||||
|
|
@ -338,10 +345,39 @@ protected:
|
|||
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
|
||||
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
|
||||
private:
|
||||
// buildViewsTree does not include some checks and is meant
|
||||
// for recursive use, use buildNewViews() for first call
|
||||
LLFolderViewItem* buildViewsTree(const LLUUID& id,
|
||||
const LLUUID& parent_id,
|
||||
LLInventoryObject const* objectp,
|
||||
LLFolderViewItem *target_view,
|
||||
LLFolderViewFolder *parent_folder_view);
|
||||
|
||||
bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
|
||||
bool mViewsInitialized; // Views have been generated
|
||||
};
|
||||
|
||||
|
||||
class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
|
||||
{};
|
||||
|
||||
void initFromParams(const Params& p);
|
||||
bool isSelectionRemovable() { return false; }
|
||||
void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
|
||||
|
||||
protected:
|
||||
LLInventoryFavoriteItemsPanel(const Params& params);
|
||||
~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
|
||||
void updateFavoritesRootFolder();
|
||||
|
||||
boost::signals2::connection mFolderChangedSignal;
|
||||
boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
|
||||
friend class LLUICtrlFactory;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* Asset Pre-Filtered Inventory Panel related class */
|
||||
/* Exchanges filter's flexibility for speed of generation and */
|
||||
|
|
@ -373,7 +409,7 @@ public:
|
|||
std::string& tooltip_msg) override;
|
||||
|
||||
protected:
|
||||
/*virtual*/ LLFolderViewItem* buildNewViews(const LLUUID& id) override;
|
||||
/*virtual*/ bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) override;
|
||||
/*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
LLLandmarkList gLandmarkList;
|
||||
|
||||
// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
|
||||
// which is 4096, to not overfill the pool if user has more than 4K of landmarks,
|
||||
// and low number helps with not flooding server with requests
|
||||
// which is 4096, to not overfill the pool if user has more than 4K of landmarks
|
||||
// and it should leave some space for other potential simultaneous asset request
|
||||
const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
|
||||
|
||||
|
||||
|
|
@ -98,7 +98,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
|
|||
|
||||
if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
|
||||
{
|
||||
// Postpone download till queu is emptier
|
||||
// Workarounds for corutines pending list size limit:
|
||||
// Postpone download till queue is emptier.
|
||||
// Coroutines have own built in 'pending' list, but unfortunately
|
||||
// it is too small compared to potential amount of landmarks
|
||||
// or assets.
|
||||
mWaitList.insert(asset_uuid);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -176,17 +180,27 @@ void LLLandmarkList::processGetAssetReply(
|
|||
// todo: this should clean mLoadedCallbackMap!
|
||||
}
|
||||
|
||||
if (!gLandmarkList.mWaitList.empty())
|
||||
// getAssetData can fire callback immediately, causing
|
||||
// a recursion which is suboptimal for very large wait list.
|
||||
// 'scheduling' indicates that we are inside request and
|
||||
// shouldn't be launching more requests.
|
||||
static bool scheduling = false;
|
||||
if (!scheduling && !gLandmarkList.mWaitList.empty())
|
||||
{
|
||||
// start new download from wait list
|
||||
landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
|
||||
LLUUID asset_uuid = *iter;
|
||||
gLandmarkList.mWaitList.erase(iter);
|
||||
gAssetStorage->getAssetData(asset_uuid,
|
||||
LLAssetType::AT_LANDMARK,
|
||||
LLLandmarkList::processGetAssetReply,
|
||||
NULL);
|
||||
gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
|
||||
scheduling = true;
|
||||
while (!gLandmarkList.mWaitList.empty() && gLandmarkList.mRequestedList.size() < MAX_SIMULTANEOUS_REQUESTS)
|
||||
{
|
||||
// start new download from wait list
|
||||
landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
|
||||
LLUUID asset_uuid = *iter;
|
||||
gLandmarkList.mWaitList.erase(iter);
|
||||
gAssetStorage->getAssetData(asset_uuid,
|
||||
LLAssetType::AT_LANDMARK,
|
||||
LLLandmarkList::processGetAssetReply,
|
||||
NULL);
|
||||
gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
|
||||
}
|
||||
scheduling = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,16 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
|
|||
messages.back()[LL_IM_TEXT] = im_text;
|
||||
}
|
||||
|
||||
std::string remove_utf8_bom(const char* buf)
|
||||
{
|
||||
std::string res(buf);
|
||||
if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
|
||||
{
|
||||
res.erase(0, 3);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
|
||||
{
|
||||
LLSINGLETON(LLLogChatTimeScanner);
|
||||
|
|
@ -417,7 +427,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string line(buffer);
|
||||
std::string line(remove_utf8_bom(buffer));
|
||||
|
||||
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
|
||||
if (' ' == line[0])
|
||||
|
|
@ -805,7 +815,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
|
|||
{
|
||||
//matching a timestamp
|
||||
boost::match_results<std::string::const_iterator> matches;
|
||||
if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
|
||||
if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
|
@ -1126,7 +1136,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
|
|||
firstline = FALSE;
|
||||
continue;
|
||||
}
|
||||
std::string line(buffer);
|
||||
std::string line(remove_utf8_bom(buffer));
|
||||
|
||||
//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
|
||||
if (' ' == line[0])
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@
|
|||
// locking actions. In particular, the following operations
|
||||
// on LLMeshRepository are very averse to any stalls:
|
||||
// * loadMesh
|
||||
// * getMeshHeader (For structural details, see:
|
||||
// * search in mMeshHeader (For structural details, see:
|
||||
// http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format)
|
||||
// * notifyLoadedMeshes
|
||||
// * getSkinInfo
|
||||
|
|
@ -1911,6 +1911,12 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
|
|||
{
|
||||
LLMutexLock lock(mMutex);
|
||||
mLoadedQ.push(mesh);
|
||||
// LLPointer is not thread safe, since we added this pointer into
|
||||
// threaded list, make sure counter gets decreased inside mutex lock
|
||||
// and won't affect mLoadedQ processing
|
||||
volume = NULL;
|
||||
// might be good idea to turn mesh into pointer to avoid making a copy
|
||||
mesh.mVolume = NULL;
|
||||
}
|
||||
return MESH_OK;
|
||||
}
|
||||
|
|
@ -2863,12 +2869,12 @@ void LLMeshRepoThread::notifyLoadedMeshes()
|
|||
mMutex->unlock();
|
||||
break;
|
||||
}
|
||||
LoadedMesh mesh = mLoadedQ.front();
|
||||
LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point
|
||||
mLoadedQ.pop();
|
||||
mMutex->unlock();
|
||||
|
||||
update_metrics = true;
|
||||
if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0)
|
||||
if (mesh.mVolume->getNumVolumeFaces() > 0)
|
||||
{
|
||||
gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
|
||||
}
|
||||
|
|
@ -3213,7 +3219,6 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
|
|||
header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
|
||||
header = iter->second;
|
||||
}
|
||||
gMeshRepo.mThread->mHeaderMutex->unlock();
|
||||
|
||||
if (header_bytes > 0
|
||||
&& !header.has("404")
|
||||
|
|
@ -3234,7 +3239,10 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
|
|||
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
|
||||
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
|
||||
|
||||
S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
|
||||
// Do not unlock mutex untill we are done with LLSD.
|
||||
// LLSD is smart and can work like smart pointer, is not thread safe.
|
||||
gMeshRepo.mThread->mHeaderMutex->unlock();
|
||||
|
||||
S32 bytes = lod_bytes + header_bytes;
|
||||
|
||||
|
||||
|
|
@ -3270,6 +3278,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
|
|||
{
|
||||
LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
|
||||
|
||||
gMeshRepo.mThread->mHeaderMutex->unlock();
|
||||
|
||||
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
|
||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||
for (int i(0); i < 4; ++i)
|
||||
|
|
@ -4139,42 +4149,42 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
|
|||
|
||||
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
|
||||
{
|
||||
LLSD mesh = mThread->getMeshHeader(mesh_id);
|
||||
if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (mesh_id.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLModel::Decomposition* decomp = getDecomposition(mesh_id);
|
||||
if (decomp && !decomp->mHull.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (mThread->hasPhysicsShapeInHeader(mesh_id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
LLModel::Decomposition* decomp = getDecomposition(mesh_id);
|
||||
if (decomp && !decomp->mHull.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
|
||||
bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
|
||||
LLMutexLock lock(mHeaderMutex);
|
||||
if (mMeshHeaderSize[mesh_id] > 0)
|
||||
{
|
||||
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
|
||||
if (iter != mMeshHeader.end())
|
||||
{
|
||||
LLSD &mesh = iter->second;
|
||||
if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mThread->getMeshHeader(mesh_id);
|
||||
}
|
||||
|
||||
LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
|
||||
{
|
||||
static LLSD dummy_ret;
|
||||
if (mesh_id.notNull())
|
||||
{
|
||||
LLMutexLock lock(mHeaderMutex);
|
||||
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
|
||||
if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
return dummy_ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ public:
|
|||
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
LLSD& getMeshHeader(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
|
||||
|
||||
void notifyLoadedMeshes();
|
||||
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
|
|
@ -595,9 +595,6 @@ public:
|
|||
|
||||
bool meshUploadEnabled();
|
||||
bool meshRezEnabled();
|
||||
|
||||
|
||||
LLSD& getMeshHeader(const LLUUID& mesh_id);
|
||||
|
||||
void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
|
||||
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
|
||||
|
|
|
|||
|
|
@ -245,6 +245,12 @@ LLModelPreview::~LLModelPreview()
|
|||
{
|
||||
mModelLoader->shutdown();
|
||||
}
|
||||
|
||||
if (mPreviewAvatar)
|
||||
{
|
||||
mPreviewAvatar->markDead();
|
||||
mPreviewAvatar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLModelPreview::calcResourceCost()
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "llavatariconctrl.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewermenu.h" // is_agent_mappable
|
||||
#include "llvoiceclient.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltrans.h"
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "lllandmarkactions.h"
|
||||
#include "llparcel.h"
|
||||
#include "llslurl.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
|
|
@ -77,7 +78,7 @@ BOOL LLPanelLandmarkInfo::postBuild()
|
|||
mCreator = getChild<LLTextBox>("creator");
|
||||
mCreated = getChild<LLTextBox>("created");
|
||||
|
||||
mLandmarkTitle = getChild<LLTextBox>("title_value");
|
||||
mLandmarkTitle = getChild<LLLineEditor>("title_value");
|
||||
mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
|
||||
mNotesEditor = getChild<LLTextEditor>("notes_editor");
|
||||
mFolderCombo = getChild<LLComboBox>("folder_combo");
|
||||
|
|
@ -113,6 +114,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
|
|||
landmark_info_panel->setVisible(type == LANDMARK);
|
||||
|
||||
getChild<LLTextBox>("folder_label")->setVisible(is_info_type_create_landmark);
|
||||
getChild<LLButton>("edit_btn")->setVisible(!is_info_type_create_landmark);
|
||||
mFolderCombo->setVisible(is_info_type_create_landmark);
|
||||
|
||||
switch(type)
|
||||
|
|
@ -126,13 +128,10 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
|
|||
mNotesEditor->setEnabled(TRUE);
|
||||
|
||||
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
|
||||
std::string name = parcel_mgr->getAgentParcelName();
|
||||
LLParcel* parcel = parcel_mgr->getAgentParcel();
|
||||
std::string name = parcel->getName();
|
||||
LLVector3 agent_pos = gAgent.getPositionAgent();
|
||||
|
||||
std::string desc;
|
||||
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos);
|
||||
mNotesEditor->setText(desc);
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
S32 region_x = ll_round(agent_pos.mV[VX]);
|
||||
|
|
@ -147,6 +146,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string desc;
|
||||
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
|
||||
region_name = desc;
|
||||
}
|
||||
|
|
@ -159,6 +159,25 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
|
|||
mLandmarkTitleEditor->setText(name);
|
||||
}
|
||||
|
||||
LLUUID owner_id = parcel->getOwnerID();
|
||||
if (owner_id.notNull())
|
||||
{
|
||||
if (parcel->getIsGroupOwned())
|
||||
{
|
||||
std::string owner_name = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
|
||||
mParcelOwner->setText(owner_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
|
||||
mParcelOwner->setText(owner_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mParcelOwner->setText(getString("public"));
|
||||
}
|
||||
|
||||
// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo()
|
||||
// because we use only agent's current coordinates instead of waiting for
|
||||
// remote parcel request to complete.
|
||||
|
|
@ -210,6 +229,24 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
|
|||
mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
|
||||
}
|
||||
|
||||
if (parcel_data.owner_id.notNull())
|
||||
{
|
||||
if (parcel_data.flags & 0x4) // depends onto DRTSIM-453
|
||||
{
|
||||
std::string owner_name = LLSLURL("group", parcel_data.owner_id, "inspect").getSLURLString();
|
||||
mParcelOwner->setText(owner_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string owner_name = LLSLURL("agent", parcel_data.owner_id, "inspect").getSLURLString();
|
||||
mParcelOwner->setText(owner_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mParcelOwner->setText(getString("public"));
|
||||
}
|
||||
|
||||
LLSD info;
|
||||
info["update_verbs"] = true;
|
||||
info["global_x"] = parcel_data.global_x;
|
||||
|
|
@ -264,7 +301,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
|
|||
}
|
||||
else
|
||||
{
|
||||
mOwner->setText(getString("public"));
|
||||
std::string public_str = getString("public");
|
||||
mOwner->setText(public_str);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
|
|
@ -311,6 +349,7 @@ void LLPanelLandmarkInfo::toggleLandmarkEditMode(BOOL enabled)
|
|||
mNotesEditor->setReadOnly(!enabled);
|
||||
mFolderCombo->setVisible(enabled);
|
||||
getChild<LLTextBox>("folder_label")->setVisible(enabled);
|
||||
getChild<LLButton>("edit_btn")->setVisible(!enabled);
|
||||
|
||||
// HACK: To change the text color in a text editor
|
||||
// when it was enabled/disabled we set the text once again.
|
||||
|
|
@ -357,7 +396,7 @@ void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
|
|||
// If no parcel exists use the region name instead.
|
||||
if (name.empty())
|
||||
{
|
||||
name = mRegionName->getText();
|
||||
name = mRegionTitle;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private:
|
|||
LLTextBox* mOwner;
|
||||
LLTextBox* mCreator;
|
||||
LLTextBox* mCreated;
|
||||
LLTextBox* mLandmarkTitle;
|
||||
LLLineEditor* mLandmarkTitle;
|
||||
LLLineEditor* mLandmarkTitleEditor;
|
||||
LLTextEditor* mNotesEditor;
|
||||
LLComboBox* mFolderCombo;
|
||||
|
|
|
|||
|
|
@ -227,6 +227,12 @@ BOOL LLLandmarksPanel::postBuild()
|
|||
initMyInventoryPanel();
|
||||
initLibraryInventoryPanel();
|
||||
|
||||
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
|
||||
if (accordion)
|
||||
{
|
||||
accordion->setSkipScrollToChild(true);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remem
|
|||
{
|
||||
sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
|
||||
LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
|
||||
remember_password->setValue(remember_psswrd);
|
||||
remember_password->setValue(remember_user && remember_psswrd);
|
||||
remember_password->setEnabled(remember_user);
|
||||
sInstance->populateUserList(credential);
|
||||
}
|
||||
|
|
@ -687,7 +687,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
|
|||
|
||||
if (LLPanelLogin::sInstance->mPasswordModified)
|
||||
{
|
||||
authenticator = LLSD::emptyMap();
|
||||
// password is plaintext
|
||||
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
|
||||
authenticator["secret"] = password;
|
||||
|
|
@ -698,6 +697,15 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
|
|||
if (credential.notNull())
|
||||
{
|
||||
authenticator = credential->getAuthenticator();
|
||||
if (authenticator.emptyMap())
|
||||
{
|
||||
// Likely caused by user trying to log in to non-system grid
|
||||
// with unsupported name format, just retry
|
||||
LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
|
||||
// password is plaintext
|
||||
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
|
||||
authenticator["secret"] = password;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1137,7 +1145,11 @@ void LLPanelLogin::onRememberUserCheck(void*)
|
|||
remember_name->setValue(true);
|
||||
LLNotificationsUtil::add("LoginCantRemoveUsername");
|
||||
}
|
||||
remember_psswrd->setEnabled(remember);
|
||||
if (!remember)
|
||||
{
|
||||
remember_psswrd->setValue(false);
|
||||
}
|
||||
remember_psswrd->setEnabled(remember);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "llagent.h"
|
||||
#include "llexpandabletextbox.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llhttpconstants.h"
|
||||
|
|
@ -78,6 +79,7 @@ BOOL LLPanelPlaceInfo::postBuild()
|
|||
mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
|
||||
mRegionName = getChild<LLTextBox>("region_title");
|
||||
mParcelName = getChild<LLTextBox>("parcel_title");
|
||||
mParcelOwner = getChild<LLTextBox>("parcel_owner");
|
||||
mDescEditor = getChild<LLExpandableTextBox>("description");
|
||||
|
||||
mMaturityRatingIcon = getChild<LLIconCtrl>("maturity_icon");
|
||||
|
|
@ -98,11 +100,13 @@ void LLPanelPlaceInfo::resetLocation()
|
|||
mParcelID.setNull();
|
||||
mRequestedID.setNull();
|
||||
mPosRegion.clearVec();
|
||||
mRegionTitle.clear();
|
||||
|
||||
std::string loading = LLTrans::getString("LoadingData");
|
||||
mMaturityRatingText->setValue(loading);
|
||||
mRegionName->setText(loading);
|
||||
mRegionName->setTextArg("[REGIONAMEPOS]", loading);
|
||||
mParcelName->setText(loading);
|
||||
mParcelOwner->setText(loading);
|
||||
mDescEditor->setText(loading);
|
||||
mMaturityRatingIcon->setValue(LLUUID::null);
|
||||
|
||||
|
|
@ -182,9 +186,11 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
|
|||
|
||||
std::string not_available = getString("not_available");
|
||||
mMaturityRatingText->setValue(not_available);
|
||||
mRegionName->setText(not_available);
|
||||
mRegionName->setTextArg("[REGIONAMEPOS]", not_available);
|
||||
mParcelName->setText(not_available);
|
||||
mParcelOwner->setText(not_available);
|
||||
mMaturityRatingIcon->setValue(LLUUID::null);
|
||||
mRegionTitle.clear();
|
||||
|
||||
// Enable "Back" button that was disabled when parcel request was sent.
|
||||
getChild<LLButton>("back_btn")->setEnabled(TRUE);
|
||||
|
|
@ -198,12 +204,34 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
|
|||
mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
|
||||
}
|
||||
|
||||
if(!parcel_data.sim_name.empty())
|
||||
{
|
||||
mRegionName->setText(parcel_data.sim_name);
|
||||
S32 region_x;
|
||||
S32 region_y;
|
||||
S32 region_z;
|
||||
|
||||
// If the region position is zero, grab position from the global
|
||||
if (mPosRegion.isExactlyZero())
|
||||
{
|
||||
region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
|
||||
region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
|
||||
region_z = ll_round(parcel_data.global_z);
|
||||
}
|
||||
else
|
||||
{
|
||||
region_x = ll_round(mPosRegion.mV[VX]);
|
||||
region_y = ll_round(mPosRegion.mV[VY]);
|
||||
region_z = ll_round(mPosRegion.mV[VZ]);
|
||||
}
|
||||
|
||||
if (!parcel_data.sim_name.empty())
|
||||
{
|
||||
mRegionTitle = parcel_data.sim_name;
|
||||
std::string name_and_pos = llformat("%s (%d, %d, %d)",
|
||||
mRegionTitle.c_str(), region_x, region_y, region_z);
|
||||
mRegionName->setTextArg("[REGIONAMEPOS]", name_and_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRegionTitle.clear();
|
||||
mRegionName->setText(LLStringUtil::null);
|
||||
}
|
||||
|
||||
|
|
@ -216,30 +244,11 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
|
|||
mDescEditor->setText(getString("not_available"));
|
||||
}
|
||||
|
||||
S32 region_x;
|
||||
S32 region_y;
|
||||
S32 region_z;
|
||||
|
||||
// If the region position is zero, grab position from the global
|
||||
if(mPosRegion.isExactlyZero())
|
||||
{
|
||||
region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
|
||||
region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
|
||||
region_z = ll_round(parcel_data.global_z);
|
||||
}
|
||||
else
|
||||
{
|
||||
region_x = ll_round(mPosRegion.mV[VX]);
|
||||
region_y = ll_round(mPosRegion.mV[VY]);
|
||||
region_z = ll_round(mPosRegion.mV[VZ]);
|
||||
}
|
||||
|
||||
if (!parcel_data.name.empty())
|
||||
{
|
||||
mParcelTitle = parcel_data.name;
|
||||
|
||||
mParcelName->setText(llformat("%s (%d, %d, %d)",
|
||||
mParcelTitle.c_str(), region_x, region_y, region_z));
|
||||
mParcelName->setText(mParcelTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -280,12 +289,10 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
|
||||
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
|
||||
{
|
||||
std::string region_name = mRegionName->getText();
|
||||
|
||||
LLPickData data;
|
||||
data.pos_global = pos_global;
|
||||
data.name = mParcelTitle.empty() ? region_name : mParcelTitle;
|
||||
data.sim_name = region_name;
|
||||
data.name = mParcelTitle.empty() ? mRegionTitle : mParcelTitle;
|
||||
data.sim_name = mRegionTitle;
|
||||
data.desc = mDescEditor->getText();
|
||||
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
data.parcel_id = mParcelID;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ protected:
|
|||
LLUUID mRequestedID;
|
||||
LLVector3 mPosRegion;
|
||||
std::string mParcelTitle; // used for pick title without coordinates
|
||||
std::string mRegionTitle;
|
||||
std::string mCurrentTitle;
|
||||
S32 mScrollingPanelMinHeight;
|
||||
S32 mScrollingPanelWidth;
|
||||
|
|
@ -120,6 +121,7 @@ protected:
|
|||
LLTextureCtrl* mSnapshotCtrl;
|
||||
LLTextBox* mRegionName;
|
||||
LLTextBox* mParcelName;
|
||||
LLTextBox* mParcelOwner;
|
||||
LLExpandableTextBox* mDescEditor;
|
||||
LLIconCtrl* mMaturityRatingIcon;
|
||||
LLTextBox* mMaturityRatingText;
|
||||
|
|
|
|||
|
|
@ -104,8 +104,6 @@ BOOL LLPanelPlaceProfile::postBuild()
|
|||
mForSalePanel->getChild<LLIconCtrl>("icon_for_sale")->
|
||||
setMouseDownCallback(boost::bind(&LLPanelPlaceProfile::onForSaleBannerClick, this));
|
||||
|
||||
mParcelOwner = getChild<LLTextBox>("owner_value");
|
||||
|
||||
mParcelRatingIcon = getChild<LLIconCtrl>("rating_icon");
|
||||
mParcelRatingText = getChild<LLTextBox>("rating_value");
|
||||
mVoiceIcon = getChild<LLIconCtrl>("voice_icon");
|
||||
|
|
@ -183,7 +181,6 @@ void LLPanelPlaceProfile::resetLocation()
|
|||
mYouAreHerePanel->setVisible(FALSE);
|
||||
|
||||
std::string loading = LLTrans::getString("LoadingData");
|
||||
mParcelOwner->setValue(loading);
|
||||
|
||||
mParcelRatingIcon->setValue(loading);
|
||||
mParcelRatingText->setText(loading);
|
||||
|
|
@ -248,14 +245,14 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type)
|
|||
const S32 SEARCH_DESC_HEIGHT = 150;
|
||||
|
||||
// Remember original geometry (once).
|
||||
static const S32 sOrigDescVPad = getChildView("parcel_title")->getRect().mBottom - mDescEditor->getRect().mTop;
|
||||
static const S32 sOrigDescVPad = getChildView("owner_label")->getRect().mBottom - mDescEditor->getRect().mTop;
|
||||
static const S32 sOrigDescHeight = mDescEditor->getRect().getHeight();
|
||||
static const S32 sOrigMRIconVPad = mDescEditor->getRect().mBottom - mMaturityRatingIcon->getRect().mTop;
|
||||
static const S32 sOrigMRTextVPad = mDescEditor->getRect().mBottom - mMaturityRatingText->getRect().mTop;
|
||||
|
||||
// Resize the description.
|
||||
const S32 desc_height = is_info_type_agent ? sOrigDescHeight : SEARCH_DESC_HEIGHT;
|
||||
const S32 desc_top = getChildView("parcel_title")->getRect().mBottom - sOrigDescVPad;
|
||||
const S32 desc_top = getChildView("owner_label")->getRect().mBottom - sOrigDescVPad;
|
||||
LLRect desc_rect = mDescEditor->getRect();
|
||||
desc_rect.setOriginAndSize(desc_rect.mLeft, desc_top - desc_height, desc_rect.getWidth(), desc_height);
|
||||
mDescEditor->reshape(desc_rect.getWidth(), desc_rect.getHeight());
|
||||
|
|
@ -401,6 +398,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
|
|||
parcel_data.global_x = pos_global.mdV[VX];
|
||||
parcel_data.global_y = pos_global.mdV[VY];
|
||||
parcel_data.global_z = pos_global.mdV[VZ];
|
||||
parcel_data.owner_id = parcel->getOwnerID();
|
||||
|
||||
std::string on = getString("on");
|
||||
std::string off = getString("off");
|
||||
|
|
|
|||
|
|
@ -76,8 +76,6 @@ private:
|
|||
LLPanel* mForSalePanel;
|
||||
LLPanel* mYouAreHerePanel;
|
||||
|
||||
LLTextBox* mParcelOwner;
|
||||
|
||||
LLIconCtrl* mParcelRatingIcon;
|
||||
LLTextBox* mParcelRatingText;
|
||||
LLIconCtrl* mVoiceIcon;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "lllandmarkactions.h"
|
||||
#include "lllandmarklist.h"
|
||||
#include "lllayoutstack.h"
|
||||
#include "llpanellandmarkinfo.h"
|
||||
#include "llpanellandmarks.h"
|
||||
#include "llpanelpick.h"
|
||||
|
|
@ -280,9 +281,6 @@ BOOL LLPanelPlaces::postBuild()
|
|||
mShowOnMapBtn = getChild<LLButton>("map_btn");
|
||||
mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
|
||||
|
||||
mEditBtn = getChild<LLButton>("edit_btn");
|
||||
mEditBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
|
||||
|
||||
mSaveBtn = getChild<LLButton>("save_btn");
|
||||
mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this));
|
||||
|
||||
|
|
@ -355,6 +353,9 @@ BOOL LLPanelPlaces::postBuild()
|
|||
LLComboBox* folder_combo = mLandmarkInfo->getChild<LLComboBox>("folder_combo");
|
||||
folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
|
||||
|
||||
LLButton* edit_btn = mLandmarkInfo->getChild<LLButton>("edit_btn");
|
||||
edit_btn->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
|
||||
|
||||
createTabs();
|
||||
updateVerbs();
|
||||
|
||||
|
|
@ -532,7 +533,6 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
|
|||
BOOL is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) &&
|
||||
mItem->getPermissions().allowModifyBy(gAgent.getID());
|
||||
|
||||
mEditBtn->setEnabled(is_landmark_editable);
|
||||
mSaveBtn->setEnabled(is_landmark_editable);
|
||||
|
||||
if (is_landmark_editable)
|
||||
|
|
@ -1216,13 +1216,16 @@ void LLPanelPlaces::updateVerbs()
|
|||
|
||||
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);
|
||||
mSaveBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCancelBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
|
||||
bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;
|
||||
mOverflowBtn->setVisible(show_options_btn);
|
||||
getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);
|
||||
getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn);
|
||||
|
||||
mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
|
||||
|
||||
if (is_place_info_visible)
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ private:
|
|||
LLButton* mPlaceProfileBackBtn;
|
||||
LLButton* mTeleportBtn;
|
||||
LLButton* mShowOnMapBtn;
|
||||
LLButton* mEditBtn;
|
||||
LLButton* mSaveBtn;
|
||||
LLButton* mCancelBtn;
|
||||
LLButton* mCloseBtn;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ public:
|
|||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
|
||||
|
||||
registrar.add("Gear.Edit", boost::bind(&edit_outfit));
|
||||
registrar.add("Gear.TouchAttach", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_attachment_touch));
|
||||
registrar.add("Gear.EditItem", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_item_edit));
|
||||
registrar.add("Gear.EditOutfit", boost::bind(&edit_outfit));
|
||||
registrar.add("Gear.TakeOff", boost::bind(&LLPanelWearing::onRemoveItem, mPanelWearing));
|
||||
registrar.add("Gear.Copy", boost::bind(&LLPanelWearing::copyToClipboard, mPanelWearing));
|
||||
|
||||
|
|
@ -78,6 +80,16 @@ public:
|
|||
LLToggleableMenu* getMenu() { return mMenu; }
|
||||
|
||||
private:
|
||||
void handleMultiple(std::function<void(const LLUUID& id)> functor)
|
||||
{
|
||||
uuid_vec_t selected_item_ids;
|
||||
mPanelWearing->getSelectedItemsUUIDs(selected_item_ids);
|
||||
|
||||
for (const LLUUID& item_id : selected_item_ids)
|
||||
{
|
||||
functor(item_id);
|
||||
}
|
||||
}
|
||||
|
||||
LLToggleableMenu* mMenu;
|
||||
LLPanelWearing* mPanelWearing;
|
||||
|
|
@ -92,7 +104,9 @@ protected:
|
|||
{
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
|
||||
registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
|
||||
registrar.add("Wearing.TouchAttach", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
|
||||
registrar.add("Wearing.EditItem", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
|
||||
registrar.add("Wearing.EditOutfit", boost::bind(&edit_outfit));
|
||||
registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front()));
|
||||
registrar.add("Wearing.TakeOff",
|
||||
boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
|
||||
|
|
@ -138,14 +152,19 @@ protected:
|
|||
}
|
||||
|
||||
// Enable/disable some menu items depending on the selection.
|
||||
bool show_touch = !bp_selected && !clothes_selected && attachments_selected;
|
||||
bool show_edit = bp_selected || clothes_selected || attachments_selected;
|
||||
bool allow_detach = !bp_selected && !clothes_selected && attachments_selected;
|
||||
bool allow_take_off = !bp_selected && clothes_selected && !attachments_selected;
|
||||
|
||||
menu->setItemVisible("touch_attach", show_touch);
|
||||
menu->setItemEnabled("touch_attach", 1 == mUUIDs.size() && enable_attachment_touch(mUUIDs.front()));
|
||||
menu->setItemVisible("edit_item", show_edit);
|
||||
menu->setItemEnabled("edit_item", 1 == mUUIDs.size() && get_is_item_editable(mUUIDs.front()));
|
||||
menu->setItemVisible("take_off", allow_take_off);
|
||||
menu->setItemVisible("detach", allow_detach);
|
||||
menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);
|
||||
menu->setItemVisible("edit_outfit_separator", show_touch | show_edit | allow_take_off || allow_detach);
|
||||
menu->setItemVisible("show_original", mUUIDs.size() == 1);
|
||||
menu->setItemVisible("edit_item", FALSE);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -173,12 +192,15 @@ protected:
|
|||
|
||||
void updateMenuItemsVisibility(LLContextMenu* menu)
|
||||
{
|
||||
menu->setItemVisible("touch_attach", TRUE);
|
||||
menu->setItemEnabled("touch_attach", 1 == mUUIDs.size());
|
||||
menu->setItemVisible("edit_item", TRUE);
|
||||
menu->setItemEnabled("edit_item", 1 == mUUIDs.size());
|
||||
menu->setItemVisible("take_off", FALSE);
|
||||
menu->setItemVisible("detach", TRUE);
|
||||
menu->setItemVisible("edit_outfit_separator", TRUE);
|
||||
menu->setItemVisible("edit_outfit_separator", FALSE);
|
||||
menu->setItemVisible("show_original", FALSE);
|
||||
menu->setItemVisible("edit_item", TRUE);
|
||||
menu->setItemVisible("edit", FALSE);
|
||||
menu->setItemVisible("edit_outfit", FALSE);
|
||||
}
|
||||
|
||||
LLPanelWearing* mPanelWearing;
|
||||
|
|
@ -350,6 +372,18 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
|
|||
}
|
||||
}
|
||||
|
||||
uuid_vec_t selected_uuids;
|
||||
getSelectedItemsUUIDs(selected_uuids);
|
||||
|
||||
if (command_name == "touch_attach")
|
||||
{
|
||||
return (1 == selected_uuids.size()) && (enable_attachment_touch(selected_uuids.front()));
|
||||
}
|
||||
else if (command_name == "edit_item")
|
||||
{
|
||||
return (1 == selected_uuids.size()) && (get_is_item_editable(selected_uuids.front()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue