Merge branch 'master' into DRTVWR-520-apple-notarization

master
Andrey Lihatskiy 2020-11-11 22:45:54 +02:00
commit b9bcfad195
231 changed files with 3121 additions and 1717 deletions

View File

@ -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>

View File

@ -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

View File

@ -180,7 +180,7 @@ LLApp::~LLApp()
if(mExceptionHandler != 0) delete mExceptionHandler;
SUBSYSTEM_CLEANUP(LLCommon);
SUBSYSTEM_CLEANUP_DBG(LLCommon);
}
// static

View File

@ -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();

View File

@ -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;
}

View File

@ -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) */

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -1017,8 +1017,8 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
}
else
{
// disable any default verification for server certs
// Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
// disable any default verification for server certs
// Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
}
// set the verification callback.

View File

@ -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
///----------------------------------------------------------------------------

View File

@ -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
//--------------------------------------------------------------------

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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(); }

View File

@ -359,7 +359,6 @@ protected:
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
LLSD mSettings;
bool mIsValid;
LLSD cloneSettings() const;

View File

@ -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());

View File

@ -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
}

View File

@ -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");

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 );

View File

@ -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());
}

View File

@ -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();

View File

@ -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())) )

View File

@ -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;

View File

@ -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";

View File

@ -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;
}
}

View File

@ -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");
}

View File

@ -2147,7 +2147,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")

View File

@ -1 +1 @@
6.4.11
6.4.12

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -30,8 +30,6 @@
#include "llsingleton.h"
class LLViewerInventoryItem;
//--------------------------------------------------------------------------------
// LLAttachmentsMgr
//

View File

@ -31,7 +31,6 @@
#include "lliconctrl.h"
#include "llavatarpropertiesprocessor.h"
#include "llviewermenu.h"
class LLAvatarName;

View File

@ -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;

View File

@ -57,7 +57,6 @@
#include "llinventorymodel.h"
#include "llmultigesture.h"
#include "llui.h"
#include "llviewermenu.h"
#include "lluictrlfactory.h"
//

View File

@ -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");

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llchatitemscontainerctrl.h"
#include "llchatmsgbox.h"
#include "lltextbox.h"
#include "llavataractions.h"

View File

@ -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,

View File

@ -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");

View File

@ -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;
}
};
//////////////////////////////////////////////////////////////////////////

View File

@ -36,7 +36,6 @@
// Classes
//
class LLColor4;
class LLFloaterColorPicker;
class LLColorSwatchCtrl
: public LLUICtrl

View File

@ -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);

View File

@ -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"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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());

View File

@ -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; }

View File

@ -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();
}

View File

@ -34,6 +34,7 @@
#include "lloutputmonitorctrl.h"
class LLTextBox;
class LLFloater;
class LLFloaterIMContainer;
class LLConversationViewSession;
class LLConversationViewParticipant;

View File

@ -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"

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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;

View File

@ -34,6 +34,7 @@
class LLSpinCtrl;
class LLSnapshotLivePreview;
class LLToolset;
class LLFloaterSnapshotBase : public LLFloater
{

View File

@ -33,7 +33,6 @@
#define LL_LLFLOATERWORLDMAP_H
#include "llfloater.h"
#include "llhudtext.h"
#include "llmapimagetype.h"
#include "lltracker.h"
#include "llslurl.h"

View File

@ -102,7 +102,7 @@ protected:
static void sortObjects();
LLHUDObject(const U8 type);
~LLHUDObject();
virtual ~LLHUDObject();
virtual void render() = 0;
virtual void renderForTimer() {};

View File

@ -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();
}

View File

@ -6379,6 +6379,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);
@ -6529,6 +6537,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())

View File

@ -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.

View File

@ -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);

View File

@ -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
@ -678,17 +679,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)
{
@ -903,16 +946,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)
@ -2648,29 +2704,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;
@ -2678,43 +2742,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
{
@ -2727,62 +2781,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;
}

View File

@ -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),
@ -512,7 +512,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);
@ -555,7 +566,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())
{
@ -852,7 +869,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);
}
@ -862,11 +879,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;
@ -887,7 +936,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;
@ -896,7 +945,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;
@ -973,26 +1022,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);
@ -1789,21 +1864,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)

View File

@ -325,8 +325,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;
@ -334,10 +341,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 */
@ -369,7 +405,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:

View File

@ -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;
}
}

View File

@ -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])

View File

@ -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;
}

View File

@ -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,

View File

@ -245,6 +245,12 @@ LLModelPreview::~LLModelPreview()
{
mModelLoader->shutdown();
}
if (mPreviewAvatar)
{
mPreviewAvatar->markDead();
mPreviewAvatar = NULL;
}
}
U32 LLModelPreview::calcResourceCost()

View File

@ -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"

View File

@ -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;
}
}

View File

@ -71,7 +71,7 @@ private:
LLTextBox* mOwner;
LLTextBox* mCreator;
LLTextBox* mCreated;
LLTextBox* mLandmarkTitle;
LLLineEditor* mLandmarkTitle;
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLComboBox* mFolderCombo;

View File

@ -227,6 +227,12 @@ BOOL LLLandmarksPanel::postBuild()
initMyInventoryPanel();
initLibraryInventoryPanel();
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
if (accordion)
{
accordion->setSkipScrollToChild(true);
}
return TRUE;
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -76,8 +76,6 @@ private:
LLPanel* mForSalePanel;
LLPanel* mYouAreHerePanel;
LLTextBox* mParcelOwner;
LLIconCtrl* mParcelRatingIcon;
LLTextBox* mParcelRatingText;
LLIconCtrl* mVoiceIcon;

View File

@ -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)

View File

@ -121,7 +121,6 @@ private:
LLButton* mPlaceProfileBackBtn;
LLButton* mTeleportBtn;
LLButton* mShowOnMapBtn;
LLButton* mEditBtn;
LLButton* mSaveBtn;
LLButton* mCancelBtn;
LLButton* mCloseBtn;

Some files were not shown because too many files have changed in this diff Show More