Ansariel 2021-06-25 16:02:59 +02:00
commit e893536a3a
319 changed files with 7750 additions and 4554 deletions

View File

@ -362,6 +362,8 @@ Chaser Zaks
BUG-227485
Cherry Cheevers
ChickyBabes Zuzu
Chorazin Allen
BUG-229753
Christopher Organiser
Ciaran Laval
Cinder Roxley

View File

@ -34,6 +34,10 @@
#include <iostream>
#include "apr_base64.h"
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
// </FS:Beq pp Rye>
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
@ -2177,60 +2181,223 @@ std::string zip_llsd(LLSD& data)
// not very efficient -- creats a copy of decompressed LLSD block in memory
// and deserializes from that copy using LLSDSerialize
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
{
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
// U8* result = NULL;
// U32 cur_size = 0;
// z_stream strm;
// const U32 CHUNK = 65536;
// U8 *in = new(std::nothrow) U8[size];
// if (!in)
// {
// return ZR_MEM_ERROR;
// }
// is.read((char*) in, size);
// U8 out[CHUNK];
// strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL;
// strm.opaque = Z_NULL;
// strm.avail_in = size;
// strm.next_in = in;
// S32 ret = inflateInit(&strm);
// do
// {
// strm.avail_out = CHUNK;
// strm.next_out = out;
// ret = inflate(&strm, Z_NO_FLUSH);
// if (ret == Z_STREAM_ERROR)
// {
// LL_DEBUGS() << "Unzip error: Z_STREAM_ERROR" << LL_ENDL; // <FS>
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// return ZR_DATA_ERROR;
// }
// switch (ret)
// {
// case Z_NEED_DICT:
// ret = Z_DATA_ERROR;
// case Z_DATA_ERROR:
// case Z_MEM_ERROR:
// LL_DEBUGS() << "Unzip error: " << ret << LL_ENDL; // <FS>
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// return ZR_MEM_ERROR;
// break;
// }
// U32 have = CHUNK-strm.avail_out;
// U8* new_result = (U8*)realloc(result, cur_size + have);
// if (new_result == NULL)
// {
// inflateEnd(&strm);
// if (result)
// {
// free(result);
// }
// delete[] in;
// return ZR_MEM_ERROR;
// }
// result = new_result;
// memcpy(result+cur_size, out, have);
// cur_size += have;
// } while (ret == Z_OK);
// inflateEnd(&strm);
// delete [] in;
// if (ret != Z_STREAM_END)
// {
// LL_DEBUGS() << "Unzip error: !Z_STREAM_END" << LL_ENDL; // <FS>
// // free(result);
// if( result )
// free(result);
// return ZR_DATA_ERROR;
// }
// //result now points to the decompressed LLSD block
// {
// std::istringstream istr;
// // Since we are using this for meshes, data we are dealing with tend to be large.
// // So string can potentially fail to allocate, make sure this won't cause problems
// try
// {
// std::string res_str((char*)result, cur_size);
// std::string deprecated_header("<? LLSD/Binary ?>");
// if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
// {
// res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
// }
// cur_size = res_str.size();
// istr.str(res_str);
// }
// #ifdef LL_WINDOWS
// catch (std::length_error)
// {
// // free(result);
// if( result )
// free(result);
// return ZR_SIZE_ERROR;
// }
// #endif
// catch (std::bad_alloc&)
// {
// // free(result);
// if( result )
// free(result);
// return ZR_MEM_ERROR;
// }
// if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
// {
// // free(result);
// if( result )
// free(result);
// return ZR_PARSE_ERROR;
// }
// }
// // free(result);
// if( result )
// free(result);
// return ZR_OK;
std::unique_ptr<U8[]> in;
try
{
in = std::unique_ptr<U8[]>(new U8[size]);
}
catch(const std::bad_alloc&)
{
return ZR_MEM_ERROR;
}
is.read((char*) in.get(), size);
return unzip_llsd(data, in.get(), size);
}
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size)
{
U8* result = NULL;
U32 cur_size = 0;
z_stream strm;
const U32 CHUNK = 65536;
constexpr U32 CHUNK = 1024 * 256;
U8 *in = new(std::nothrow) U8[size];
if (!in)
static thread_local std::unique_ptr<U8[]> out;
if (!out)
{
return ZR_MEM_ERROR;
try
{
out = std::unique_ptr<U8[]>(new U8[CHUNK]);
}
catch (const std::bad_alloc&)
{
return ZR_MEM_ERROR;
}
}
is.read((char*) in, size);
U8 out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
strm.next_in = in;
strm.next_in = const_cast<U8*>(in);
S32 ret = inflateInit(&strm);
switch (ret)
{
case Z_STREAM_ERROR:
return ZR_DATA_ERROR;
case Z_VERSION_ERROR:
return ZR_VERSION_ERROR;
case Z_MEM_ERROR:
return ZR_MEM_ERROR;
}
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
strm.next_out = out.get();
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
{
LL_DEBUGS() << "Unzip error: Z_STREAM_ERROR" << LL_ENDL; // <FS>
inflateEnd(&strm);
// free(result);
if( result )
free(result);
delete [] in;
return ZR_DATA_ERROR;
}
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
LL_DEBUGS() << "Unzip error: " << ret << LL_ENDL; // <FS>
{
inflateEnd(&strm);
// free(result);
if( result )
free(result);
delete [] in;
free(result);
return ZR_DATA_ERROR;
}
case Z_STREAM_ERROR:
case Z_BUF_ERROR:
{
inflateEnd(&strm);
free(result);
return ZR_BUFFER_ERROR;
}
case Z_MEM_ERROR:
{
inflateEnd(&strm);
free(result);
return ZR_MEM_ERROR;
break;
}
}
U32 have = CHUNK-strm.avail_out;
@ -2243,111 +2410,200 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
{
free(result);
}
delete[] in;
return ZR_MEM_ERROR;
}
result = new_result;
memcpy(result+cur_size, out, have);
memcpy(result+cur_size, out.get(), have);
cur_size += have;
} while (ret == Z_OK);
} while (ret == Z_OK && ret != Z_STREAM_END);
inflateEnd(&strm);
delete [] in;
if (ret != Z_STREAM_END)
{
LL_DEBUGS() << "Unzip error: !Z_STREAM_END" << LL_ENDL; // <FS>
// free(result);
if( result )
free(result);
free(result);
return ZR_DATA_ERROR;
}
//result now points to the decompressed LLSD block
{
std::istringstream istr;
// Since we are using this for meshes, data we are dealing with tend to be large.
// So string can potentially fail to allocate, make sure this won't cause problems
try
{
std::string res_str((char*)result, cur_size);
char* result_ptr = strip_deprecated_header((char*)result, cur_size);
std::string deprecated_header("<? LLSD/Binary ?>");
if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
{
res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
}
cur_size = res_str.size();
istr.str(res_str);
}
#ifdef LL_WINDOWS
catch (std::length_error)
boost::iostreams::stream<boost::iostreams::array_source> istrm(result_ptr, cur_size);
if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH))
{
// free(result);
if( result )
free(result);
return ZR_SIZE_ERROR;
}
#endif
catch (std::bad_alloc&)
{
// free(result);
if( result )
free(result);
return ZR_MEM_ERROR;
}
if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
{
// free(result);
if( result )
free(result);
free(result);
return ZR_PARSE_ERROR;
}
}
// free(result);
if( result )
free(result);
free(result);
return ZR_OK;
}
// </FS:Beq pp Rye>
//This unzip function will only work with a gzip header and trailer - while the contents
//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
//and trailers are different for the formats.
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
{
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
// if (size == 0)
// {
// LL_WARNS() << "No data to unzip." << LL_ENDL;
// return NULL;
// }
// U8* result = NULL;
// U32 cur_size = 0;
// z_stream strm;
// const U32 CHUNK = 0x4000;
// U8 *in = new(std::nothrow) U8[size];
// if (in == NULL)
// {
// LL_WARNS() << "Memory allocation failure." << LL_ENDL;
// return NULL;
// }
// is.read((char*) in, size);
// U8 out[CHUNK];
// strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL;
// strm.opaque = Z_NULL;
// strm.avail_in = size;
// strm.next_in = in;
// valid = true; // <FS:ND/> Default is all okay.
// S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
// do
// {
// strm.avail_out = CHUNK;
// strm.next_out = out;
// ret = inflate(&strm, Z_NO_FLUSH);
// if (ret == Z_STREAM_ERROR)
// {
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
// valid = false;
// }
// switch (ret)
// {
// case Z_NEED_DICT:
// ret = Z_DATA_ERROR;
// case Z_DATA_ERROR:
// case Z_MEM_ERROR:
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// valid = false;
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
// break;
// }
// if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc.
// U32 have = CHUNK-strm.avail_out;
// U8* new_result = (U8*) realloc(result, cur_size + have);
// if (new_result == NULL)
// {
// LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
// << " bytes; requested " << cur_size + have
// << " bytes; total syze: ." << size << " bytes."
// << LL_ENDL;
// inflateEnd(&strm);
// if (result)
// {
// free(result);
// }
// delete[] in;
// valid = false;
// return NULL;
// }
// result = new_result;
// memcpy(result+cur_size, out, have);
// cur_size += have;
// } // </FS:ND>
// } while (ret == Z_OK);
// inflateEnd(&strm);
// delete [] in;
// if (ret != Z_STREAM_END)
// {
// // <FS:ND> result might have been freed above. And calling free with a null pointer is not defined.
// // free(result);
// if( result )
// free(result);
// // </FS:ND>
// valid = false;
// return NULL;
// }
// //result now points to the decompressed LLSD block
// {
// outsize= cur_size;
// valid = true;
// }
// return result;
// }
if (size == 0)
{
LL_WARNS() << "No data to unzip." << LL_ENDL;
return NULL;
return nullptr;
}
std::unique_ptr<U8[]> in;
try
{
in = std::make_unique<U8[]>(size);
}
catch (const std::bad_alloc&)
{
LL_WARNS() << "Memory allocation failure." << LL_ENDL;
return nullptr;
}
is.read((char*) in.get(), size);
return unzip_llsdNavMesh(valid, outsize, in.get(), size);
}
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 size )
{
if (size == 0)
{
LL_WARNS() << "No data to unzip." << LL_ENDL;
return nullptr;
}
U8* result = NULL;
U32 cur_size = 0;
z_stream strm;
const U32 CHUNK = 0x4000;
U8 *in = new(std::nothrow) U8[size];
if (in == NULL)
{
LL_WARNS() << "Memory allocation failure." << LL_ENDL;
return NULL;
}
is.read((char*) in, size);
U8 out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
strm.next_in = in;
strm.next_in = const_cast<U8*>(in);
valid = true; // <FS:ND/> Default is all okay.
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
do
{
@ -2357,32 +2613,23 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&strm);
// free(result);
if( result )
free(result);
delete [] in;
in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
valid = false;
free(result);
return NULL;
}
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
// [[fallthrough]]; // <FS:Beq> TODO when we have C++17 compilation.
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
// free(result);
if( result )
free(result);
delete [] in;
free(result);
valid = false;
in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
break;
return NULL;
}
if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc.
U32 have = CHUNK-strm.avail_out;
U8* new_result = (U8*) realloc(result, cur_size + have);
@ -2397,7 +2644,6 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
{
free(result);
}
delete[] in;
valid = false;
return NULL;
}
@ -2405,21 +2651,13 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
memcpy(result+cur_size, out, have);
cur_size += have;
} // </FS:ND>
} while (ret == Z_OK);
inflateEnd(&strm);
delete [] in;
if (ret != Z_STREAM_END)
{
// <FS:ND> result might have been freed above. And calling free with a null pointer is not defined.
// free(result);
if( result )
free(result);
// </FS:ND>
free(result);
valid = false;
return NULL;
}
@ -2433,4 +2671,22 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
return result;
}
char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size)
{
const char* deprecated_header = "<? LLSD/Binary ?>";
constexpr size_t deprecated_header_size = 17;
if (cur_size > deprecated_header_size
&& memcmp(in, deprecated_header, deprecated_header_size) == 0)
{
in = in + deprecated_header_size;
cur_size = cur_size - deprecated_header_size;
if (header_size)
{
*header_size = deprecated_header_size + 1;
}
}
return in;
}
// </FS:Beq pp Rye>

View File

@ -858,9 +858,14 @@ public:
ZR_SIZE_ERROR,
ZR_DATA_ERROR,
ZR_PARSE_ERROR,
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
ZR_BUFFER_ERROR,
ZR_VERSION_ERROR
// </FS:Beq>
} EZipRresult;
// return OK or reason for failure
static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size); // <FS:Beq pp Rye/> Add non-allocating variants of unzip_llsd
};
//dirty little zip functions -- yell at davep
@ -868,4 +873,10 @@ LL_COMMON_API std::string zip_llsd(LLSD& data);
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
LL_COMMON_API U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, const U8* in, S32 size);
// returns a pointer to the array or past the array if the deprecated header exists
LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr);
// </FS:Beq>
#endif // LL_LLSDSERIALIZE_H

View File

@ -71,6 +71,7 @@ void LLDiskCache::purge()
LL_INFOS() << "Total dir size before purge is " << dirFileSize(mCacheDir) << LL_ENDL;
}
boost::system::error_code ec;
auto start_time = std::chrono::high_resolution_clock::now();
typedef std::pair<std::time_t, std::pair<uintmax_t, std::string>> file_info_t;
@ -81,19 +82,27 @@ void LLDiskCache::purge()
#else
std::string cache_path(mCacheDir);
#endif
if (boost::filesystem::is_directory(cache_path))
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
{
// <FS:Ansariel> Optimize asset simple disk cache
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path), {}))
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path, ec), {}))
{
if (boost::filesystem::is_regular_file(entry))
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
uintmax_t file_size = boost::filesystem::file_size(entry);
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
if (ec.failed())
{
continue;
}
const std::string file_path = entry.path().string();
const std::time_t file_time = boost::filesystem::last_write_time(entry);
const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
if (ec.failed())
{
continue;
}
file_info.push_back(file_info_t(file_time, { file_size, file_path }));
}
@ -119,7 +128,6 @@ void LLDiskCache::purge()
action = "DELETE:";
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
//boost::filesystem::remove(entry.second.second);
boost::system::error_code ec;
boost::filesystem::remove(entry.second.second, ec);
if (ec.failed())
{
@ -253,9 +261,15 @@ void LLDiskCache::updateFileAccessTime(const std::string& file_path)
// current time
const std::time_t cur_time = std::time(nullptr);
boost::system::error_code ec;
#if LL_WINDOWS
// file last write time
const std::time_t last_write_time = boost::filesystem::last_write_time(utf8str_to_utf16str(file_path));
const std::time_t last_write_time = boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), ec);
if (ec.failed())
{
LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
return;
}
// delta between cur time and last time the file was written
const std::time_t delta_time = cur_time - last_write_time;
@ -264,11 +278,16 @@ void LLDiskCache::updateFileAccessTime(const std::string& file_path)
// before the last one
if (delta_time > time_threshold)
{
boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), cur_time);
boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), cur_time, ec);
}
#else
// file last write time
const std::time_t last_write_time = boost::filesystem::last_write_time(file_path);
const std::time_t last_write_time = boost::filesystem::last_write_time(file_path, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
return;
}
// delta between cur time and last time the file was written
const std::time_t delta_time = cur_time - last_write_time;
@ -277,9 +296,14 @@ void LLDiskCache::updateFileAccessTime(const std::string& file_path)
// before the last one
if (delta_time > time_threshold)
{
boost::filesystem::last_write_time(file_path, cur_time);
boost::filesystem::last_write_time(file_path, cur_time, ec);
}
#endif
if (ec.failed())
{
LL_WARNS() << "Failed to update last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
}
}
const std::string LLDiskCache::getCacheInfo()
@ -305,24 +329,24 @@ void LLDiskCache::clearCache()
* the component files but it's called infrequently so it's
* likely just fine
*/
boost::system::error_code ec;
#if LL_WINDOWS
std::wstring cache_path(utf8str_to_utf16str(mCacheDir));
#else
std::string cache_path(mCacheDir);
#endif
if (boost::filesystem::is_directory(cache_path))
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
{
// <FS:Ansariel> Optimize asset simple disk cache
//for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path), {}))
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path, ec), {}))
{
if (boost::filesystem::is_regular_file(entry))
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
//boost::filesystem::remove(entry);
boost::system::error_code ec;
boost::filesystem::remove(entry, ec);
if (ec.failed())
{
@ -348,22 +372,27 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)
* so if performance is ever an issue, optimizing this or removing it altogether,
* is an easy win.
*/
boost::system::error_code ec;
#if LL_WINDOWS
std::wstring dir_path(utf8str_to_utf16str(dir));
#else
std::string dir_path(dir);
#endif
if (boost::filesystem::is_directory(dir_path))
if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
{
// <FS:Ansariel> Optimize asset simple disk cache
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(dir_path), {}))
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(dir_path, ec), {}))
{
if (boost::filesystem::is_regular_file(entry))
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
total_file_size += boost::filesystem::file_size(entry);
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
if (!ec.failed())
{
total_file_size += file_size;
}
}
}
}

View File

@ -295,7 +295,6 @@ public:
void setAllowTerraform(BOOL b){setParcelFlag(PF_ALLOW_TERRAFORM, b); }
void setAllowDamage(BOOL b) { setParcelFlag(PF_ALLOW_DAMAGE, b); }
void setAllowFly(BOOL b) { setParcelFlag(PF_ALLOW_FLY, b); }
void setAllowLandmark(BOOL b){ setParcelFlag(PF_ALLOW_LANDMARK, b); }
void setAllowGroupScripts(BOOL b) { setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); }
void setAllowOtherScripts(BOOL b) { setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); }
void setAllowDeedToGroup(BOOL b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); }
@ -476,11 +475,6 @@ public:
BOOL getAllowFly() const
{ return (mParcelFlags & PF_ALLOW_FLY) ? TRUE : FALSE; }
// Remove permission restrictions for creating landmarks.
// We should eventually remove this flag completely.
BOOL getAllowLandmark() const
{ return TRUE; }
BOOL getAllowGroupScripts() const
{ return (mParcelFlags & PF_ALLOW_GROUP_SCRIPTS) ? TRUE : FALSE; }

View File

@ -33,7 +33,7 @@ const U32 PF_ALLOW_FLY = 1 << 0;// Can start flying
const U32 PF_ALLOW_OTHER_SCRIPTS= 1 << 1;// Scripts by others can run.
const U32 PF_FOR_SALE = 1 << 2;// Can buy this land
const U32 PF_FOR_SALE_OBJECTS = 1 << 7;// Can buy all objects on this land
const U32 PF_ALLOW_LANDMARK = 1 << 3;
const U32 PF_ALLOW_LANDMARK = 1 << 3;// Always true/deprecated
const U32 PF_ALLOW_TERRAFORM = 1 << 4;
const U32 PF_ALLOW_DAMAGE = 1 << 5;
const U32 PF_CREATE_OBJECTS = 1 << 6;

View File

@ -2403,7 +2403,27 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
return false;
}
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
{
//input stream is now pointing at a zlib compressed block of LLSD
//decompress block
LLSD mdl;
U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
return false;
}
return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
{
// </FS:Beq pp Rye>
{
U32 face_count = mdl.size();

View File

@ -1099,7 +1099,13 @@ protected:
void createVolumeFaces();
public:
virtual bool unpackVolumeFaces(std::istream& is, S32 size);
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
bool unpackVolumeFaces(U8* in_data, S32 size);
private:
bool unpackVolumeFacesInternal(const LLSD& mdl);
public:
// </FS:Beq pp Rye>
virtual void setMeshAssetLoaded(BOOL loaded);
virtual BOOL isMeshAssetLoaded();

View File

@ -124,6 +124,7 @@ set(llui_SOURCE_FILES
lluictrl.cpp
lluictrlfactory.cpp
lluistring.cpp
lluiusage.cpp
llundo.cpp
llurlaction.cpp
llurlentry.cpp
@ -245,6 +246,7 @@ set(llui_HEADER_FILES
llui.h
lluicolor.h
lluistring.h
lluiusage.h
llundo.h
llurlaction.h
llurlentry.h

View File

@ -47,6 +47,7 @@
#include "llnotificationsutil.h"
#include "llrender.h"
#include "lluictrlfactory.h"
#include "lluiusage.h"
#include "llhelp.h"
#include "lldockablefloater.h"
#include "llviewereventrecorder.h"
@ -494,6 +495,13 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
setFocus(TRUE);
}
if (!mFunctionName.empty())
{
LL_DEBUGS("UIUsage") << "calling mouse down function " << mFunctionName << LL_ENDL;
LLUIUsage::instance().logCommand(mFunctionName);
LLUIUsage::instance().logControl(getPathname());
}
/*
* ATTENTION! This call fires another mouse down callback.
* If you wish to remove this call emit that signal directly

View File

@ -37,7 +37,8 @@ typedef enum e_chat_source_type
CHAT_SOURCE_SYSTEM = 0,
CHAT_SOURCE_AGENT = 1,
CHAT_SOURCE_OBJECT = 2,
CHAT_SOURCE_UNKNOWN = 3
CHAT_SOURCE_TELEPORT = 3,
CHAT_SOURCE_UNKNOWN = 4
} EChatSourceType;
typedef enum e_chat_type
@ -69,6 +70,7 @@ typedef enum e_chat_style
CHAT_STYLE_NORMAL,
CHAT_STYLE_IRC,
CHAT_STYLE_HISTORY,
CHAT_STYLE_TELEPORT_SEP,
CHAT_STYLE_MODERATOR
}EChatStyle;

View File

@ -58,6 +58,7 @@
#include "llhelp.h"
#include "llmultifloater.h"
#include "llsdutil.h"
#include "lluiusage.h"
#include <boost/foreach.hpp>
@ -213,6 +214,8 @@ LLFloater::Params::Params()
open_callback("open_callback"),
close_callback("close_callback"),
follows("follows"),
rel_x("rel_x", 0),
rel_y("rel_y", 0),
hosted_floater_show_titlebar("hosted_floater_show_titlebar", true) // <FS:Ansariel> MultiFloater without titlebar for hosted floater
{
changeDefault(visible, false);
@ -284,6 +287,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mHasBeenDraggedWhileMinimized(FALSE),
mPreviousMinimizedBottom(0),
mPreviousMinimizedLeft(0),
mDefaultRelativeX(p.rel_x),
mDefaultRelativeY(p.rel_y),
mMinimizeSignal(NULL),
mHostedFloaterShowtitlebar(p.hosted_floater_show_titlebar) // <FS:Ansariel> MultiFloater without titlebar for hosted floater
// mNotificationContext(NULL)
@ -540,7 +545,12 @@ void LLFloater::destroy()
// virtual
LLFloater::~LLFloater()
{
LLFloaterReg::removeInstance(mInstanceName, mKey);
if (!isDead())
{
// If it's dead, instance is supposed to be already removed, and
// in case of single instance we can remove new one by accident
LLFloaterReg::removeInstance(mInstanceName, mKey);
}
if( gFocusMgr.childHasKeyboardFocus(this))
{
@ -1021,6 +1031,15 @@ bool LLFloater::applyRectControl()
saved_rect = true;
}
else if ((mDefaultRelativeX != 0) && (mDefaultRelativeY != 0))
{
mPosition.mX = mDefaultRelativeX;
mPosition.mY = mDefaultRelativeY;
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
applyRelativePosition();
saved_rect = true;
}
// remember updated position
if (rect_specified)
@ -1720,6 +1739,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
// virtual
void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key)
{
LLUIUsage::instance().logFloater(getInstanceName());
LLMultiFloater* hostp = getHost();
if (hostp)
{
@ -3525,6 +3545,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mSingleInstance = p.single_instance;
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
mDefaultRelativeX = p.rel_x;
mDefaultRelativeY = p.rel_y;
mPositioning = p.positioning;
mHostedFloaterShowtitlebar = p.hosted_floater_show_titlebar; // <FS:Ansariel> MultiFloater without titlebar for hosted floater

View File

@ -178,6 +178,9 @@ public:
label_v_padding, // <FS:Zi> Make vertical label padding a per-skin option
legacy_header_height; // HACK see initFromXML()
Optional<F32> rel_x,
rel_y;
// Images for top-right controls
Optional<LLUIImage*> close_image,
snooze_image, // <FS:Ansariel> FIRE-11724: Snooze group chat
@ -547,6 +550,9 @@ private:
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
F32 mDefaultRelativeX;
F32 mDefaultRelativeY;
// <FS:Ansariel> MultiFloater without titlebar for hosted floater
bool mHostedFloaterShowtitlebar;
};

View File

@ -32,6 +32,7 @@
#include "llfloater.h"
#include "llmultifloater.h"
#include "llfloaterreglistener.h"
#include "lluiusage.h"
#include <string>
//*******************************************************
@ -73,6 +74,12 @@ void LLFloaterReg::addWithFileCallback(const std::string& name, const LLFloaterF
}
// [/SL:KB]
//static
bool LLFloaterReg::isRegistered(const std::string& name)
{
return sBuildMap.find(name) != sBuildMap.end();
}
//static
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
{
@ -513,7 +520,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
std::string name = sdname.asString();
LLFloater* instance = getInstance(name, key);
if (!instance)
{
LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;

View File

@ -104,6 +104,7 @@ public:
static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,
const std::string& groupname = LLStringUtil::null);
static bool isRegistered(const std::string& name);
// [SL:KB] - Patch: UI-Base | Checked: 2010-12-01 (Catznip-3.0.0a) | Added: Catznip-2.4.0g
static void addWithFileCallback(const std::string& name, const LLFloaterFileFunc& fileFunc, const LLFloaterBuildFunc& func,

View File

@ -292,6 +292,9 @@ public:
void resetContextMenu() { setContextMenu(NULL); };
void setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; }
void setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; }
// <FS:Ansariel> Make these protected
void removeChar();
void removeWord(bool prev);

View File

@ -80,7 +80,7 @@ const U32 LEFT_PAD_PIXELS = 3;
const U32 LEFT_WIDTH_PIXELS = 15;
const U32 LEFT_PLAIN_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS;
const U32 RIGHT_PAD_PIXELS = 2;
const U32 RIGHT_PAD_PIXELS = 7;
const U32 RIGHT_WIDTH_PIXELS = 15;
const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS;
@ -96,7 +96,7 @@ const std::string SEPARATOR_NAME("separator");
const std::string VERTICAL_SEPARATOR_LABEL( "|" );
const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK
const std::string LLMenuGL::BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
const std::string LLMenuGL::BRANCH_SUFFIX( "\xe2\x96\xb8" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
const std::string LLMenuGL::ARROW_UP ("^^^^^^^");
const std::string LLMenuGL::ARROW_DOWN("vvvvvvv");

View File

@ -77,6 +77,7 @@ LLNotificationForm::FormButton::FormButton()
text("text"),
ignore("ignore"),
is_default("default"),
width("width", 0),
type("type")
{
// set type here so it gets serialized

View File

@ -190,6 +190,7 @@ public:
Mandatory<std::string> text;
Optional<std::string> ignore;
Optional<bool> is_default;
Optional<S32> width;
Mandatory<std::string> type;

View File

@ -34,7 +34,11 @@
LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
: LLUICtrl(p),
mSearchButton(NULL),
mClearButton(NULL)
mClearButton(NULL),
mEditorImage(p.background_image),
mEditorImageFocused(p.background_image_focused),
mEditorSearchImage(p.background_image_highlight),
mHighlightTextField(p.highlight_text_field)
{
S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;
S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad;
@ -57,6 +61,8 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
// Set up line editor.
LLLineEditor::Params line_editor_params(p);
line_editor_params.name("filter edit box");
line_editor_params.background_image(p.background_image);
line_editor_params.background_image_focused(p.background_image_focused);
line_editor_params.rect(getLocalRect());
line_editor_params.follows.flags(FOLLOWS_ALL);
line_editor_params.text_pad_left(text_pad_left);
@ -104,6 +110,20 @@ void LLSearchEditor::draw()
if (mClearButton)
mClearButton->setVisible(!mSearchEditor->getWText().empty());
if (mHighlightTextField)
{
if (!mSearchEditor->getWText().empty())
{
mSearchEditor->setBgImage(mEditorSearchImage);
mSearchEditor->setBgImageFocused(mEditorSearchImage);
}
else
{
mSearchEditor->setBgImage(mEditorImage);
mSearchEditor->setBgImageFocused(mEditorImageFocused);
}
}
LLUICtrl::draw();
}

View File

@ -47,14 +47,23 @@ public:
Optional<LLButton::Params> search_button,
clear_button;
Optional<bool> search_button_visible,
clear_button_visible;
clear_button_visible,
highlight_text_field;
Optional<commit_callback_t> keystroke_callback;
Optional<LLUIImage*> background_image,
background_image_focused,
background_image_highlight;
Params()
: search_button("search_button"),
search_button_visible("search_button_visible"),
clear_button("clear_button"),
clear_button_visible("clear_button_visible")
clear_button_visible("clear_button_visible"),
highlight_text_field("highlight_text_field"),
background_image("background_image"),
background_image_focused("background_image_focused"),
background_image_highlight("background_image_highlight")
{}
};
@ -93,6 +102,13 @@ protected:
LLLineEditor* mSearchEditor;
LLButton* mSearchButton;
LLButton* mClearButton;
LLPointer<LLUIImage> mEditorImage;
LLPointer<LLUIImage> mEditorImageFocused;
LLPointer<LLUIImage> mEditorSearchImage;
LLPointer<LLUIImage> mEditorSearchImageFocused;
bool mHighlightTextField;
};
#endif // LL_SEARCHEDITOR_H

View File

@ -38,6 +38,7 @@
#include "llrender.h"
#include "llfloater.h"
#include "lltrans.h"
#include "lluiusage.h"
//----------------------------------------------------------------------------
@ -1716,6 +1717,8 @@ BOOL LLTabContainer::setTab(S32 which)
if (is_selected)
{
LLUIUsage::instance().logPanel(tuple->mTabPanel->getName());
// Make sure selected tab is within scroll region
if (mIsVertical)
{

View File

@ -1167,6 +1167,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
executeStopParam.function_name = executeStopFunction;
executeStopParam.parameter = commandp->executeStopParameters();
LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam);
button->setFunctionName(commandp->executeFunctionName());
LL_DEBUGS("UIUsage") << "button function name a -> " << commandp->executeFunctionName() << LL_ENDL;
LLUICtrl::commit_callback_t stop_func = initCommitCallback(executeStopParam);
button->setMouseDownCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2));
@ -1174,7 +1176,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
}
else
{
// <FS:Ansariel> Check enabled state of button before executing!
button->setFunctionName(commandp->executeFunctionName());
LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL; // <FS:Ansariel> Check enabled state of button before executing!
//button->setCommitCallback(executeParam);
LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam);
button->setCommitCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2));

View File

@ -35,6 +35,7 @@
#include "lluictrlfactory.h"
#include "lltabcontainer.h"
#include "llaccordionctrltab.h"
#include "lluiusage.h"
static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
@ -290,6 +291,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa
else
{
std::string function_name = cb.function_name;
setFunctionName(function_name);
commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));
if (func)
{
@ -430,7 +432,19 @@ BOOL LLUICtrl::canFocusChildren() const
void LLUICtrl::onCommit()
{
if (mCommitSignal)
(*mCommitSignal)(this, getValue());
{
if (!mFunctionName.empty())
{
LL_DEBUGS("UIUsage") << "calling commit function " << mFunctionName << LL_ENDL;
LLUIUsage::instance().logCommand(mFunctionName);
LLUIUsage::instance().logControl(getPathname());
}
else
{
//LL_DEBUGS("UIUsage") << "calling commit function " << "UNKNOWN" << LL_ENDL;
}
(*mCommitSignal)(this, getValue());
}
}
//virtual
@ -615,6 +629,12 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
// </FS:Zi>
}
}
void LLUICtrl::setFunctionName(const std::string& function_name)
{
mFunctionName = function_name;
}
// static
bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type)
{

View File

@ -197,6 +197,8 @@ public:
void setMakeVisibleControlVariable(LLControlVariable* control);
void setMakeInvisibleControlVariable(LLControlVariable* control);
void setFunctionName(const std::string& function_name);
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
virtual void setValue(const LLSD& value);
@ -326,6 +328,8 @@ protected:
LLControlVariable* mMakeInvisibleControlVariable;
boost::signals2::connection mMakeInvisibleControlConnection;
std::string mFunctionName;
static F32 sActiveControlTransparency;
static F32 sInactiveControlTransparency;

146
indra/llui/lluiusage.cpp Normal file
View File

@ -0,0 +1,146 @@
/**
* @file lluiuisage.cpp
* @brief Source file for LLUIUsage
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lluiusage.h"
#include <boost/algorithm/string.hpp>
LLUIUsage::LLUIUsage()
{
}
LLUIUsage::~LLUIUsage()
{
}
// static
std::string LLUIUsage::sanitized(const std::string& s)
{
// Remove characters that make the ViewerStats db unhappy
std::string result(s);
std::replace(result.begin(), result.end(), '.', '_');
std::replace(result.begin(), result.end(), ' ', '_');
return result;
}
// static
void LLUIUsage::setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val)
{
// Keep the last max_elts components of the specified path
std::vector<std::string> fields;
boost::split(fields, path, boost::is_any_of("/"));
auto first_pos = std::max(fields.begin(), fields.end() - max_elts);
auto end_pos = fields.end();
std::vector<std::string> last_fields(first_pos,end_pos);
setLLSDNested(sd, last_fields, val);
}
// setLLSDNested()
// Accomplish the equivalent of
// sd[fields[0]][fields[1]]... = val;
// for an arbitrary number of fields.
// This might be useful as an LLSD utility function; is not specific to LLUIUsage
//
// static
void LLUIUsage::setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val)
{
LLSD* fsd = &sd;
for (auto it=fields.begin(); it!=fields.end(); ++it)
{
if (it == fields.end()-1)
{
(*fsd)[*it] = val;
}
else
{
if (!(*fsd)[*it].isMap())
{
(*fsd)[*it] = LLSD::emptyMap();
}
fsd = &(*fsd)[*it];
}
}
}
void LLUIUsage::logCommand(const std::string& command)
{
mCommandCounts[sanitized(command)]++;
LL_DEBUGS("UIUsage") << "command " << command << LL_ENDL;
}
void LLUIUsage::logControl(const std::string& control)
{
mControlCounts[sanitized(control)]++;
LL_DEBUGS("UIUsage") << "control " << control << LL_ENDL;
}
void LLUIUsage::logFloater(const std::string& floater)
{
mFloaterCounts[sanitized(floater)]++;
LL_DEBUGS("UIUsage") << "floater " << floater << LL_ENDL;
}
void LLUIUsage::logPanel(const std::string& p)
{
mPanelCounts[sanitized(p)]++;
LL_DEBUGS("UIUsage") << "panel " << p << LL_ENDL;
}
LLSD LLUIUsage::asLLSD() const
{
LLSD result;
for (auto const& it : mCommandCounts)
{
result["commands"][it.first] = LLSD::Integer(it.second);
}
for (auto const& it : mControlCounts)
{
setLLSDPath(result["controls"], it.first, 2, LLSD::Integer(it.second));
}
for (auto const& it : mFloaterCounts)
{
result["floaters"][it.first] = LLSD::Integer(it.second);
}
for (auto const& it : mPanelCounts)
{
result["panels"][it.first] = LLSD::Integer(it.second);
}
return result;
}
// Clear up some junk content generated during initial login/UI initialization
void LLUIUsage::clear()
{
LL_DEBUGS("UIUsage") << "clear" << LL_ENDL;
mCommandCounts.clear();
mControlCounts.clear();
mFloaterCounts.clear();
mPanelCounts.clear();
}

57
indra/llui/lluiusage.h Normal file
View File

@ -0,0 +1,57 @@
/**
* @file lluiuisage.h
* @brief Header file for LLUIUsage
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLUIUSAGE_H
#define LL_LLUIUSAGE_H
#include <map>
#include "llsd.h"
#include "llsingleton.h"
// UIUsage tracking to see which operations and UI elements are most popular in a session
class LLUIUsage : public LLSingleton<LLUIUsage>
{
public:
LLSINGLETON(LLUIUsage);
~LLUIUsage();
public:
static std::string sanitized(const std::string& s);
static void setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val);
static void setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val);
void logCommand(const std::string& command);
void logControl(const std::string& control);
void logFloater(const std::string& floater);
void logPanel(const std::string& p);
LLSD asLLSD() const;
void clear();
private:
std::map<std::string,U32> mCommandCounts;
std::map<std::string,U32> mControlCounts;
std::map<std::string,U32> mFloaterCounts;
std::map<std::string,U32> mPanelCounts;
};
#endif // LLUIUIUSAGE.h

View File

@ -348,6 +348,42 @@ LLQuaternion LLVirtualTrackball::getRotation() const
return mValue;
}
// static
void LLVirtualTrackball::getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation)
{
// LLQuaternion has own function to get azimuth, but it doesn't appear to return correct values (meant for 2d?)
LLVector3 point = VectorZero * quat;
if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY]))
{
azimuth = atan2f(point.mV[VX], point.mV[VY]);
}
else
{
azimuth = 0;
}
azimuth -= F_PI_BY_TWO;
if (azimuth < 0)
{
azimuth += F_PI * 2;
}
// while vector is '1', F32 is not sufficiently precise and we can get
// values like 1.0000012 which will result in -90deg angle instead of 90deg
F32 z = llclamp(point.mV[VZ], -1.f, 1.f);
elevation = asin(z); // because VectorZero's length is '1'
}
// static
void LLVirtualTrackball::getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation)
{
getAzimuthAndElevation(quat, azimuth, elevation);
azimuth *= RAD_TO_DEG;
elevation *= RAD_TO_DEG;
}
BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)
{
if (hasMouseCapture())
@ -409,6 +445,10 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)
mValue *= az_quat;
}
// we are doing a lot of F32 mathematical operations with loss of precision,
// re-normalize to compensate
mValue.normalize();
mPrevX = x;
mPrevY = y;
onCommit();

View File

@ -96,6 +96,9 @@ public:
void setRotation(const LLQuaternion &value);
LLQuaternion getRotation() const;
static void getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation);
static void getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation);
protected:
friend class LLUICtrlFactory;
LLVirtualTrackball(const Params&);

View File

@ -318,6 +318,7 @@ set(viewer_SOURCE_FILES
llflexibleobject.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloateraddpaymentmethod.cpp
llfloaterauction.cpp
llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
@ -341,6 +342,7 @@ set(viewer_SOURCE_FILES
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
llfloaterdisplayname.cpp
@ -364,6 +366,7 @@ set(viewer_SOURCE_FILES
llfloaterhandler.cpp
llfloaterhelpbrowser.cpp
llfloaterhoverheight.cpp
llfloaterhowto.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterimsessiontab.cpp
@ -655,7 +658,7 @@ set(viewer_SOURCE_FILES
llregionposition.cpp
llremoteparcelrequest.cpp
#llsavedsettingsglue.cpp #<FS:Ansariel> Unused
llsaveoutfitcombobtn.cpp
#llsaveoutfitcombobtn.cpp #<FS:Ansariel> Unused
llscenemonitor.cpp
llsceneview.cpp
llscreenchannel.cpp
@ -748,6 +751,7 @@ set(viewer_SOURCE_FILES
llurl.cpp
llurldispatcher.cpp
llurldispatcherlistener.cpp
llurlfloaterdispatchhandler.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlwhitelist.cpp
@ -1090,6 +1094,7 @@ set(viewer_HEADER_FILES
llflexibleobject.h
llfloaterabout.h
llfloaterbvhpreview.h
llfloateraddpaymentmethod.h
llfloaterauction.h
llfloaterautoreplacesettings.h
llfloateravatar.h
@ -1113,6 +1118,7 @@ set(viewer_HEADER_FILES
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
llfloaterdisplayname.h
@ -1136,6 +1142,7 @@ set(viewer_HEADER_FILES
llfloaterhandler.h
llfloaterhelpbrowser.h
llfloaterhoverheight.h
llfloaterhowto.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterimnearbychat.h
@ -1417,7 +1424,7 @@ set(viewer_HEADER_FILES
llresourcedata.h
llrootview.h
#llsavedsettingsglue.h #<FS:Ansariel> Unused
llsaveoutfitcombobtn.h
#llsaveoutfitcombobtn.h #<FS:Ansariel> Unused
llscenemonitor.h
llsceneview.h
llscreenchannel.h
@ -1513,6 +1520,7 @@ set(viewer_HEADER_FILES
llurl.h
llurldispatcher.h
llurldispatcherlistener.h
llurlfloaterdispatchhandler.h
llurlhistory.h
llurllineeditorctrl.h
llurlwhitelist.h

View File

@ -1 +1 @@
6.4.20
6.4.21

View File

@ -94,8 +94,10 @@
icon="Command_HowTo_Icon"
label_ref="Command_HowTo_Label"
tooltip_ref="Command_HowTo_Tooltip"
execute_function="Help.ToggleHowTo"
is_running_function="Help.HowToVisible"
execute_function="Floater.ToggleOrBringToFront"
execute_parameters="guidebook"
is_running_function="Floater.IsOpen"
is_running_parameters="guidebook"
/>
<command name="inventory"
available_in_toybox="true"

View File

@ -6936,6 +6936,17 @@
<string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
-->
</map>
<key>GuidebookURL</key>
<map>
<key>Comment</key>
<string>URL for Guidebook content</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://guidebooks.secondlife.io/welcome/index.html</string>
</map>
<key>HighResSnapshot</key>
<map>
<key>Comment</key>
@ -10787,9 +10798,9 @@ Change of this parameter will affect the layout of buttons in notification toast
<string>Color4</string>
<key>Value</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>0.0</real>
<real>0.3</real>
<real>0.3</real>
<real>0.3</real>
<real>1.0</real>
</array>
</map>
@ -18079,6 +18090,51 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>VivoxVadAuto</key>
<map>
<key>Comment</key>
<string>A flag indicating if the automatic VAD is enabled (1) or disabled (0). The individual settings are ignored if the auto-mode is enabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>VivoxVadHangover</key>
<map>
<key>Comment</key>
<string>The time (in milliseconds) that it takes or the VAD to switch back to silence from speech mode after the last speech frame has been detected</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2000</integer>
</map>
<key>VivoxVadNoiseFloor</key>
<map>
<key>Comment</key>
<string>A dimensionless value between 0 and 20000 (default 576) that controls the maximum level at which the noise floor may be set at by the VAD's noise tracking</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>576</integer>
</map>
<key>VivoxVadSensitivity</key>
<map>
<key>Comment</key>
<string>
A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>VoiceCallsRejectGroup</key>
<map>
<key>Comment</key>
@ -25681,7 +25737,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>FSAutoUnmuteSounds</key>
<map>

View File

@ -140,6 +140,7 @@ public:
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
mNeedsTimeBox(true),
mTimeBoxTextBox(NULL),
mHeaderLayoutStack(NULL),
mAvatarNameCacheConnection()
@ -702,7 +703,18 @@ public:
// Make sure we use the correct font style for everything after the display name
mNameStyleParams.font.style = style_params.font.style;
if (chat.mFromName.empty()
if (mSourceType == CHAT_SOURCE_TELEPORT
&& chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP)
{
mFrom = chat.mFromName;
mNeedsTimeBox = false;
mUserNameTextBox->setValue(mFrom);
updateMinUserNameWidth();
LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor");
setTransparentColor(sep_color);
mTimeBoxTextBox->setVisible(FALSE);
}
else if (chat.mFromName.empty()
//|| mSourceType == CHAT_SOURCE_SYSTEM
// FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports
|| (mSourceType == CHAT_SOURCE_SYSTEM && mType != CHAT_TYPE_RADAR)
@ -835,8 +847,12 @@ public:
}
// FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports
break;
case CHAT_SOURCE_UNKNOWN:
case CHAT_SOURCE_TELEPORT:
icon->setValue(LLSD("Command_Destinations_Icon"));
break;
case CHAT_SOURCE_UNKNOWN:
icon->setValue(LLSD("Unknown_Icon"));
break;
}
// In case the message came from an object, save the object info
@ -870,7 +886,7 @@ public:
S32 user_name_width = user_name_rect.getWidth();
S32 time_box_width = mTimeBoxTextBox->getRect().getWidth();
if (!mTimeBoxTextBox->getVisible() && user_name_width > mMinUserNameWidth)
if (mNeedsTimeBox && !mTimeBoxTextBox->getVisible() && user_name_width > mMinUserNameWidth)
{
user_name_rect.mRight -= time_box_width;
mUserNameTextBox->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@ -1148,6 +1164,8 @@ protected:
LLStyle::Params mNameStyleParams;
bool mNeedsTimeBox;
private:
boost::signals2::connection mAvatarNameCacheConnection;
};
@ -1372,6 +1390,7 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT;
// We graying out chat history by graying out messages that contains full date in a time string
if (message_from_log && !is_conversation_log)
{
@ -1436,7 +1455,7 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
LLStyle::Params timestamp_style(body_message_params);
// out of the timestamp
if (args["show_time"].asBoolean())
if (args["show_time"].asBoolean() && !teleport_separator)
{
LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
timestamp_style.color(timestamp_color);
@ -1546,6 +1565,13 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
prependNewLineState = false;
}
else if (teleport_separator)
{
std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat");
appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>",
prependNewLineState, body_message_params);
prependNewLineState = false;
}
else
{
appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
@ -1566,7 +1592,8 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
LLDate new_message_time = LLDate::now();
bool needs_header_text = false;
if (mLastFromName == chat.mFromName
if (!teleport_separator
&& mLastFromName == chat.mFromName
&& mLastFromID == chat.mFromID
&& mLastMessageTime.notNull()
&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
@ -1590,7 +1617,14 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
p.bottom_pad = mBottomHeaderPad;
if (teleport_separator)
{
p.bottom_pad = mBottomSeparatorPad;
}
else
{
p.bottom_pad = mBottomHeaderPad;
}
if (!view)
{
LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL;
@ -1676,7 +1710,7 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
// usual messages showing
else
else if (!teleport_separator)
{
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;

View File

@ -318,8 +318,9 @@ void FSFloaterPlaceDetails::onOpen(const LLSD& key)
mGlobalPos = gAgent.getPositionGlobal();
}
LLUUID dest_folder = key["dest_folder"];
mPanelLandmarkInfo->resetLocation();
mPanelLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
mPanelLandmarkInfo->setInfoAndCreateLandmark(dest_folder);
mPanelLandmarkInfo->setHeaderVisible(FALSE);
mPanelLandmarkInfo->displayParcelInfo(LLUUID(), mGlobalPos);

View File

@ -33,6 +33,7 @@
#include "llpanelteleporthistory.h"
#include "llbutton.h"
#include "llfiltereditor.h"
#include "llmenubutton.h"
FSFloaterTeleportHistory::FSFloaterTeleportHistory(const LLSD& seed)
: LLFloater(seed),
@ -53,14 +54,6 @@ BOOL FSFloaterTeleportHistory::postBuild()
{
mHistoryPanel->setIsStandAlone(true);
mHistoryPanel->mTeleportBtn = getChild<LLButton>("teleport_btn");
mHistoryPanel->mShowOnMapBtn = getChild<LLButton>("map_btn");
mHistoryPanel->mShowProfile = getChild<LLButton>("profile_btn");
mHistoryPanel->mTeleportBtn->setClickedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleport, mHistoryPanel));
mHistoryPanel->mShowProfile->setClickedCallback(boost::bind(&LLTeleportHistoryPanel::onShowProfile, mHistoryPanel));
mHistoryPanel->mShowOnMapBtn->setClickedCallback(boost::bind(&LLTeleportHistoryPanel::onShowOnMap, mHistoryPanel));
mFilterEditor = getChild<LLFilterEditor>("Filter");
if (mFilterEditor)
{
@ -74,6 +67,12 @@ BOOL FSFloaterTeleportHistory::postBuild()
getChildView("history_placeholder")->addChild(mHistoryPanel);
mHistoryPanel->onSearchEdit("");
mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
mGearMenuButton->setMouseDownCallback(boost::bind(&FSFloaterTeleportHistory::onGearMenuClick, this));
mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn");
mSortingMenuButton->setMouseDownCallback(boost::bind(&FSFloaterTeleportHistory::onSortingMenuClick, this));
}
else
{
@ -117,3 +116,13 @@ BOOL FSFloaterTeleportHistory::handleKeyHere(KEY key, MASK mask)
return LLFloater::handleKeyHere(key, mask);
}
void FSFloaterTeleportHistory::onGearMenuClick()
{
mGearMenuButton->setMenu(mHistoryPanel->getSelectionMenu(), LLMenuButton::MP_BOTTOM_LEFT);
}
void FSFloaterTeleportHistory::onSortingMenuClick()
{
mSortingMenuButton->setMenu(mHistoryPanel->getSortingMenu(), LLMenuButton::MP_BOTTOM_LEFT);
}

View File

@ -32,6 +32,7 @@
class LLFilterEditor;
class LLTeleportHistoryPanel;
class LLMenuButton;
class FSFloaterTeleportHistory : public LLFloater
{
@ -47,9 +48,13 @@ public:
private:
void onFilterEdit(const std::string& search_string, bool force_filter);
void onGearMenuClick();
void onSortingMenuClick();
LLTeleportHistoryPanel* mHistoryPanel;
LLFilterEditor* mFilterEditor;
LLMenuButton* mGearMenuButton;
LLMenuButton* mSortingMenuButton;
};
#endif // FS_FLOATERTELEPORTHISTORY_H

View File

@ -148,7 +148,7 @@ bool RegionCrossExtrapolate::ifsaton(const LLViewerObject& vo) // true if root
}
LLViewerObject::const_child_list_t& children = vo.getChildren();
for (const auto child : children)
for (const auto &child : children)
{
if (child->isAvatar())
{

View File

@ -110,6 +110,7 @@
// [/RLVa:KB]
// Firestorm includes
#include "fsfloaternearbychat.h"
#include "fslslbridge.h"
#include "llpresetsmanager.h"
#include "NACLantispam.h"
@ -424,6 +425,7 @@ LLAgent::LLAgent() :
mTeleportFinishedSlot(),
mTeleportFailedSlot(),
mIsMaturityRatingChangingDuringTeleport(false),
mTPNeedsNeabyChatSeparator(false),
mMaturityRatingChange(0U),
mIsDoSendMaturityPreferenceToServer(false),
mMaturityPreferenceRequestId(0U),
@ -4738,6 +4740,7 @@ void LLAgent::clearTeleportRequest()
LLVoiceClient::getInstance()->setHidden(FALSE);
}
mTeleportRequest.reset();
mTPNeedsNeabyChatSeparator = false;
}
void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
@ -4746,6 +4749,12 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
mMaturityRatingChange = pMaturityRatingChange;
}
void LLAgent::sheduleTeleportIM()
{
// is supposed to be called during teleport so we are still waiting for parcel
mTPNeedsNeabyChatSeparator = true;
}
bool LLAgent::hasPendingTeleportRequest()
{
return ((mTeleportRequest != NULL) &&
@ -4793,6 +4802,12 @@ void LLAgent::startTeleportRequest()
void LLAgent::handleTeleportFinished()
{
LL_INFOS("Teleport") << "Agent handling teleport finished." << LL_ENDL;
if (mTPNeedsNeabyChatSeparator)
{
// parcel is ready at this point
addTPNearbyChatSeparator();
mTPNeedsNeabyChatSeparator = false;
}
clearTeleportRequest();
mTeleportCanceled.reset();
if (mIsMaturityRatingChangingDuringTeleport)
@ -4855,6 +4870,47 @@ void LLAgent::handleTeleportFailed()
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
mTPNeedsNeabyChatSeparator = false;
}
/*static*/
void LLAgent::addTPNearbyChatSeparator()
{
LLViewerRegion* agent_region = gAgent.getRegion();
LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (!agent_region || !agent_parcel)
{
return;
}
// <FS:Ansariel> [FS communication UI]
//LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
FSFloaterNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<FSFloaterNearbyChat>("fs_nearby_chat");
// </FS:Ansariel> [FS communication UI]
if (nearby_chat)
{
std::string location_name;
LLAgentUI::ELocationFormat format = LLAgentUI::LOCATION_FORMAT_NO_MATURITY;
// Might be better to provide slurl to chat
if (!LLAgentUI::buildLocationString(location_name, format))
{
location_name = "Teleport to new region"; // Shouldn't happen
}
LLChat chat;
chat.mFromName = location_name;
chat.mMuted = FALSE;
chat.mFromID = LLUUID::null;
chat.mSourceType = CHAT_SOURCE_TELEPORT;
chat.mChatStyle = CHAT_STYLE_TELEPORT_SEP;
chat.mText = "";
LLSD args;
args["do_not_log"] = TRUE;
nearby_chat->addMessage(chat, true, args);
}
}
/*static*/
@ -5146,10 +5202,16 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
// In SL we have uniform region size. This is normal.
// In opensim the handle will resolve to a 256m quantised world tile which the server maps back to a region
// it "should" also compensate for the local coords. Handle has been "correctly" determined already so we use global % 256
static const auto width{LLWorld::getInstance()->getRegionWidthInMeters()};
static const F32 width = REGION_WIDTH_METERS;// Note: reverted back to previous hardcode 256 for non-local. Whilst this appears incorrect server side logic expects %256 and will overshoot otherwise.
pos_local.set( fmod((F32)pos_global.mdV[VX], width),
fmod((F32)pos_global.mdV[VY], width),
(F32)pos_global.mdV[VZ] );
LL_INFOS("Teleport") << "Non-local TP:"
<< " pos_global " << pos_global
<< " region " << region_origin
<< " local " << pos_local
<< " region_handle " << handle
<< LL_ENDL;
}
if(teleportCore(is_local)) // Rather a pointless if as teleportCore currently always returns true

View File

@ -756,6 +756,7 @@ public:
void restartFailedTeleportRequest();
void clearTeleportRequest();
void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
void sheduleTeleportIM();
private:
@ -772,6 +773,7 @@ private:
boost::signals2::connection mTeleportFailedSlot;
bool mIsMaturityRatingChangingDuringTeleport;
bool mTPNeedsNeabyChatSeparator;
U8 mMaturityRatingChange;
bool hasPendingTeleportRequest();
@ -794,6 +796,7 @@ private:
void handleTeleportFinished();
void handleTeleportFailed();
static void addTPNearbyChatSeparator();
static void onCapabilitiesReceivedAfterTeleport();
//--------------------------------------------------------------------

View File

@ -59,6 +59,7 @@
#include "llslurl.h"
#include "llstartup.h"
#include "llfocusmgr.h"
#include "llurlfloaterdispatchhandler.h"
#include "llviewerjoystick.h"
#include "llallocator.h"
#include "llcalc.h"
@ -1098,6 +1099,7 @@ bool LLAppViewer::init()
// Load translations for tooltips
LLFloater::initClass();
LLUrlFloaterDispatchHandler::registerInDispatcher();
/////////////////////////////////////////////////

View File

@ -253,6 +253,19 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_
return LLTrans::getString(payment_text);
}
//static
bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data)
{
// Special accounts like M Linden don't have payment info revealed.
if (!avatar_data->caption_text.empty()) return true;
// Linden employees don't have payment info revealed
const S32 LINDEN_EMPLOYEE_INDEX = 3;
if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true;
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;

View File

@ -252,6 +252,8 @@ public:
// Used for profiles, inspectors.
static std::string paymentInfo(const LLAvatarData* avatar_data);
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);

View File

@ -59,6 +59,7 @@
#include "llmultigesture.h"
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiusage.h"
//
// Globals
@ -567,6 +568,8 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
// as soon as we say something, we no longer care about teaching the user
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;

View File

@ -136,6 +136,7 @@ public:
mUserNameFont(NULL),
mUserNameTextBox(NULL),
mTimeBoxTextBox(NULL),
mNeedsTimeBox(true),
mAvatarNameCacheConnection()
{}
@ -667,8 +668,19 @@ public:
user_name->setReadOnlyColor(style_params.readonly_color());
user_name->setColor(style_params.color());
if (chat.mFromName.empty()
|| mSourceType == CHAT_SOURCE_SYSTEM)
if (mSourceType == CHAT_SOURCE_TELEPORT
&& chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP)
{
mFrom = chat.mFromName;
mNeedsTimeBox = false;
user_name->setValue(mFrom);
updateMinUserNameWidth();
LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor");
setTransparentColor(sep_color);
mTimeBoxTextBox->setVisible(FALSE);
}
else if (chat.mFromName.empty()
|| mSourceType == CHAT_SOURCE_SYSTEM)
{
mFrom = LLTrans::getString("SECOND_LIFE");
if(!chat.mFromName.empty() && (mFrom != chat.mFromName))
@ -777,6 +789,9 @@ public:
case CHAT_SOURCE_SYSTEM:
icon->setValue(LLSD("SL_Logo"));
break;
case CHAT_SOURCE_TELEPORT:
icon->setValue(LLSD("Command_Destinations_Icon"));
break;
case CHAT_SOURCE_UNKNOWN:
icon->setValue(LLSD("Unknown_Icon"));
}
@ -815,7 +830,7 @@ public:
S32 user_name_width = user_name_rect.getWidth();
S32 time_box_width = time_box->getRect().getWidth();
if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
if (mNeedsTimeBox && !time_box->getVisible() && user_name_width > mMinUserNameWidth)
{
user_name_rect.mRight -= time_box_width;
user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@ -1028,6 +1043,8 @@ protected:
LLTextBox* mUserNameTextBox;
LLTextBox* mTimeBoxTextBox;
bool mNeedsTimeBox;
private:
boost::signals2::connection mAvatarNameCacheConnection;
};
@ -1262,6 +1279,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT;
// We graying out chat history by graying out messages that contains full date in a time string
if (message_from_log)
{
@ -1282,14 +1300,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
LLStyle::Params timestamp_style(body_message_params);
// out of the timestamp
if (args["show_time"].asBoolean())
if (args["show_time"].asBoolean() && !teleport_separator)
{
if (!message_from_log)
{
LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
timestamp_style.color(timestamp_color);
timestamp_style.readonly_color(timestamp_color);
}
if (!message_from_log)
{
LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
timestamp_style.color(timestamp_color);
timestamp_style.readonly_color(timestamp_color);
}
mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
prependNewLineState = false;
}
@ -1345,6 +1363,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
prependNewLineState, link_params);
prependNewLineState = false;
}
else if (teleport_separator)
{
std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat");
mEditor->appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>",
prependNewLineState, body_message_params);
prependNewLineState = false;
}
else
{
mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
@ -1363,8 +1388,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
p.right_pad = mRightWidgetPad;
LLDate new_message_time = LLDate::now();
if (mLastFromName == chat.mFromName
if (!teleport_separator
&& mLastFromName == chat.mFromName
&& mLastFromID == chat.mFromID
&& mLastMessageTime.notNull()
&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
@ -1387,7 +1412,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
p.bottom_pad = mBottomHeaderPad;
if (teleport_separator)
{
p.bottom_pad = mBottomSeparatorPad;
}
else
{
p.bottom_pad = mBottomHeaderPad;
}
if (!view)
{
LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL;
@ -1465,9 +1497,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
}
}
// usual messages showing
else
else if(!teleport_separator)
{
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
@ -1500,7 +1531,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
if (square_brackets)
{
message += "]";
}
}
mEditor->appendText(message, prependNewLineState, body_message_params);
prependNewLineState = false;

View File

@ -463,7 +463,7 @@ void LLCurrencyUIManager::Impl::updateUI()
if (!mUserEnteredCurrencyBuy)
{
if (!mZeroMessage.empty() && mUserCurrencyBuy == 0)
if (mUserCurrencyBuy == 0)
{
lindenAmount->setText(LLStringUtil::null);
}
@ -476,8 +476,9 @@ void LLCurrencyUIManager::Impl::updateUI()
}
}
mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", getLocalEstimate());
mPanel.getChildView("currency_est")->setVisible( hasEstimate() && mUserCurrencyBuy > 0);
std::string estimated = (mUserCurrencyBuy == 0) ? mPanel.getString("estimated_zero") : getLocalEstimate();
mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", estimated);
mPanel.getChildView("currency_est")->setVisible( hasEstimate() || mUserCurrencyBuy == 0);
mPanel.getChildView("currency_links")->setVisible( mSupportsInternationalBilling);
mPanel.getChildView("exchange_rate_note")->setVisible( mSupportsInternationalBilling);

View File

@ -918,9 +918,15 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
// MAINT-7926 Handle volumes in an animated object as a special case
// SL-937: add dynamic box handling for rigged mesh on regular avatars.
//if (volume->getAvatar() && volume->getAvatar()->isControlAvatar())
if (volume->getAvatar())
// <FS:Beq pp Rye> reduce recursive calls.
// if (volume->getAvatar())
// {
// const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents();
LLVOAvatar* avatarp = volume->getAvatar();
if (avatarp)
{
const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents();
const LLVector3* av_box = avatarp->getLastAnimExtents();
// </FS:Beq pp Rye>
LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));

View File

@ -334,7 +334,7 @@ namespace
std::istringstream llsdData(llsdRaw);
if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
{
LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
LL_WARNS() << "LLEnvironmentPushDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
}
}
@ -792,11 +792,11 @@ namespace
}
//=========================================================================
const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f);
const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
const F64Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
const F64Seconds LLEnvironment::TRANSITION_FAST(1.0f);
const F64Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
@ -1303,51 +1303,34 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
}
}
void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
{
setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
}
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
void LLEnvironment::setManualEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
{
LLSettingsBase::Seconds transitionTime(static_cast<F64>(gSavedSettings.getF32("FSEnvironmentManualTransitionTime")));
setEnvironmentWithTransition(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, transitionTime);
}
void LLEnvironment::setEnvironmentWithTransition(
EnvSelection_t env,
const LLUUID &assetId,
LLSettingsDay::Seconds daylength,
LLSettingsDay::Seconds dayoffset,
LLSettingsBase::Seconds transition,
S32 env_version)
{
LLSettingsVOBase::getSettingsAsset(assetId,
[this, env, daylength, dayoffset, transition, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
{
onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, transition, status, env_version);
});
setEnvironment(env, assetId, transitionTime, env_version);
}
// </FS:Beq>
void LLEnvironment::setEnvironment(
EnvSelection_t env,
const LLUUID &assetId,
LLSettingsDay::Seconds daylength,
LLSettingsDay::Seconds dayoffset,
S32 env_version)
void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
{
setEnvironment(env, assetId, TRANSITION_DEFAULT, env_version);
}
void LLEnvironment::setEnvironment(EnvSelection_t env,
const LLUUID &assetId,
LLSettingsBase::Seconds transition,
S32 env_version)
{
LLSettingsVOBase::getSettingsAsset(assetId,
[this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
[this, env, env_version, transition](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
{
onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version);
onSetEnvAssetLoaded(env, asset_id, settings, transition, status, env_version);
});
}
void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
LLUUID asset_id,
LLSettingsBase::ptr_t settings,
LLSettingsDay::Seconds daylength,
LLSettingsDay::Seconds dayoffset,
LLSettingsBase::Seconds transition,
S32 status,
S32 env_version)
@ -1824,9 +1807,9 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
clearEnvironment(ENV_PARCEL);
// <FS:Beq> opensim legacy windlight. Nothing we can do here as the default assets do not exist in OpenSim
LL_WARNS("ENVIRONMENT") << "No DayCycle specified - setting default" << LL_ENDL;
if(LLGridManager::getInstance()->isInSecondLife())
if (LLGridManager::getInstance()->isInSecondLife())
{
setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
updateEnvironment();
}
// </FS:Beq>
@ -1836,7 +1819,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
{
LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL;
clearEnvironment(ENV_PARCEL);
setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
updateEnvironment();
}
else
@ -3098,17 +3081,15 @@ bool LLEnvironment::loadFromSettings()
if (env_data.has("day_id"))
{
LLSettingsDay::Seconds length = LLSettingsDay::Seconds(env_data["day_length"].asInteger());
LLSettingsDay::Seconds offset = LLSettingsDay::Seconds(env_data["day_offset"].asInteger());
LLUUID assetId = env_data["day_id"].asUUID();
LLSettingsVOBase::getSettingsAsset(assetId,
[this, length, offset, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
[this, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
{
// Day should be always applied first,
// otherwise it will override sky or water that was set earlier
// so wait for asset to load before applying sky/water
onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, length, offset, TRANSITION_DEFAULT, status, NO_VERSION);
onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, TRANSITION_DEFAULT, status, NO_VERSION);
bool valid = false, has_assets = false;
loadSkyWaterFromSettings(env_data, valid, has_assets);
if (!has_assets && valid)

View File

@ -52,11 +52,11 @@ class LLEnvironment : public LLSingleton<LLEnvironment>
LOG_CLASS(LLEnvironment);
public:
static const F32Seconds TRANSITION_INSTANT;
static const F32Seconds TRANSITION_FAST;
static const F32Seconds TRANSITION_DEFAULT;
static const F32Seconds TRANSITION_SLOW;
static const F32Seconds TRANSITION_ALTITUDE;
static const F64Seconds TRANSITION_INSTANT;
static const F64Seconds TRANSITION_FAST;
static const F64Seconds TRANSITION_DEFAULT;
static const F64Seconds TRANSITION_SLOW;
static const F64Seconds TRANSITION_ALTITUDE;
static const LLUUID KNOWN_SKY_SUNRISE;
static const LLUUID KNOWN_SKY_MIDDAY;
@ -144,13 +144,10 @@ public:
void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }
void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }
void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); }
void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version);
void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, S32 env_version = NO_VERSION);
// <FS:Beq> FIRE-29926 - Allow configurable transition times
void setEnvironmentWithTransition(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 env_version = NO_VERSION);
void setManualEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
// </FS:Beq>
void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
void setSharedEnvironment();
void clearEnvironment(EnvSelection_t env);
@ -461,7 +458,7 @@ private:
void onAgentPositionHasChanged(const LLVector3 &localpos);
void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);
void handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition);

View File

@ -38,6 +38,7 @@
#include "lltooltip.h"
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llavatarnamecache.h"
#include "llclipboard.h"
#include "llinventorybridge.h"
@ -533,6 +534,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
//mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params);
//mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));
//addChild(mMoreTextBox);
//LLRect rect = mMoreTextBox->getRect();
//mMoreTextBox->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom));
if (p.chevron_button.isProvided())
{
LLButton::Params chevron_button_params(p.chevron_button);
@ -546,6 +549,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
mMoreCtrl = LLUICtrlFactory::create<LLTextBox> (more_button_params);
((LLTextBox*)mMoreCtrl)->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));
addChild(mMoreCtrl);
LLRect rect = mMoreCtrl->getRect();
mMoreCtrl->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom));
}
// </FS:Ansariel>
@ -1378,6 +1383,10 @@ bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata)
{
return isClipboardPasteable();
}
else if (param == "create_pick")
{
return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
}
return false;
}
@ -1429,6 +1438,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
LLFloaterReg::showInstance("world_map", "center");
}
}
else if (action == "create_pick")
{
LLSD args;
args["type"] = "create_pick";
args["item_id"] = item->getUUID();
LLFloaterSidePanelContainer::showPanel("places", args);
}
else if (action == "cut")
{
}
@ -1444,6 +1460,20 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
{
gInventory.removeItem(mSelectedItemID);
}
else if (action == "rename")
{
LLSD args;
args["NAME"] = item->getName();
LLSD payload;
payload["id"] = mSelectedItemID;
LLNotificationsUtil::add("RenameLandmark", args, payload, boost::bind(onRenameCommit, _1, _2));
}
else if (action == "move_to_landmarks")
{
change_item_parent(mSelectedItemID, gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
}
// Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).
// See EXT-4217 and STORM-207.
@ -1456,6 +1486,28 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
}
bool LLFavoritesBarCtrl::onRenameCommit(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (0 == option)
{
LLUUID id = notification["payload"]["id"].asUUID();
LLInventoryItem *item = gInventory.getItem(id);
std::string landmark_name = response["new_name"].asString();
LLStringUtil::trim(landmark_name);
if (!landmark_name.empty() && item && item->getName() != landmark_name)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(landmark_name);
new_item->updateServer(FALSE);
gInventory.updateItem(new_item);
}
}
return false;
}
BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
{
if (!LLClipboard::instance().hasContents())

View File

@ -94,6 +94,7 @@ protected:
bool enableSelected(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
static bool onRenameCommit(const LLSD& notification, const LLSD& response);
BOOL isClipboardPasteable() const;
void pasteFromClipboard() const;

View File

@ -0,0 +1,81 @@
/**
* @file llfloateraddpaymentmethod.cpp
* @brief LLFloaterAddPaymentMethod class implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloateraddpaymentmethod.h"
#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
#include "llweb.h"
LLFloaterAddPaymentMethod::LLFloaterAddPaymentMethod(const LLSD& key)
: LLFloater(key)
{
}
LLFloaterAddPaymentMethod::~LLFloaterAddPaymentMethod()
{
}
BOOL LLFloaterAddPaymentMethod::postBuild()
{
setCanDrag(FALSE);
getChild<LLButton>("continue_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onContinueBtn, this));
getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onCloseBtn, this));
return TRUE;
}
void LLFloaterAddPaymentMethod::onOpen(const LLSD& key)
{
centerOnScreen();
}
void LLFloaterAddPaymentMethod::onContinueBtn()
{
closeFloater();
LLNotificationsUtil::add("AddPaymentMethod", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
LLWeb::loadURL(this->getString("continue_url"));
}
});
}
void LLFloaterAddPaymentMethod::onCloseBtn()
{
closeFloater();
}
void LLFloaterAddPaymentMethod::centerOnScreen()
{
LLVector2 window_size = LLUI::getInstance()->getWindowSize();
centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
}

View File

@ -0,0 +1,52 @@
/**
* @file llfloateraddpaymentmethod.h
* @brief LLFloaterAddPaymentMethod class definition
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_FLOATER_ADDPAYMENTMETHOD_H
#define LL_FLOATER_ADDPAYMENTMETHOD_H
#include "llfloater.h"
class LLFloaterAddPaymentMethod:
public LLFloater
{
friend class LLFloaterReg;
public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
private:
LLFloaterAddPaymentMethod(const LLSD& key);
void centerOnScreen();
void onCloseBtn();
void onContinueBtn();
/*virtual*/ ~LLFloaterAddPaymentMethod();
};
#endif

View File

@ -32,6 +32,8 @@
#include "llcurrencyuimanager.h"
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lllayoutstack.h"
#include "lliconctrl.h"
#include "llnotificationsutil.h"
#include "llstatusbar.h"
#include "lltextbox.h"
@ -45,7 +47,6 @@
#include "fsgridhandler.h" // <FS:Beq> FIRE-30481 open sim buy floater fixup
#endif
static const S32 STANDARD_BUY_AMOUNT = 2000;
static const S32 MINIMUM_BALANCE_AMOUNT = 0;
class LLFloaterBuyCurrencyUI
@ -61,8 +62,8 @@ public:
LLCurrencyUIManager mManager;
bool mHasTarget;
std::string mTargetName;
S32 mTargetPrice;
S32 mRequiredAmount;
public:
void noTarget();
@ -71,6 +72,7 @@ public:
virtual BOOL postBuild();
void updateUI();
void collapsePanels(bool collapse);
virtual void draw();
virtual BOOL canClose();
@ -95,7 +97,9 @@ LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)
: LLFloater(key),
mChildren(*this),
mManager(*this)
mManager(*this),
mHasTarget(false),
mTargetPrice(0)
{
}
@ -107,15 +111,20 @@ LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()
void LLFloaterBuyCurrencyUI::noTarget()
{
mHasTarget = false;
mManager.setAmount(STANDARD_BUY_AMOUNT);
mTargetPrice = 0;
mManager.setAmount(0);
}
void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
{
mHasTarget = true;
mTargetName = name;
mTargetPrice = price;
if (!name.empty())
{
getChild<LLUICtrl>("target_price_label")->setValue(name);
}
S32 balance = gStatusBar->getBalance();
S32 need = price - balance;
if (need < 0)
@ -123,7 +132,8 @@ void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
need = 0;
}
mManager.setAmount(need + MINIMUM_BALANCE_AMOUNT);
mRequiredAmount = need + MINIMUM_BALANCE_AMOUNT;
mManager.setAmount(0);
}
@ -134,6 +144,13 @@ BOOL LLFloaterBuyCurrencyUI::postBuild()
getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this));
getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this));
#ifdef OPENSIM
if (LLGridManager::instance().isInOpenSim())
{
getChild<LLTextBox>("currency_links")->setText(LLStringExplicit(""));
}
#endif
center();
@ -178,7 +195,6 @@ void LLFloaterBuyCurrencyUI::updateUI()
getChildView("purchase_warning_repurchase")->setVisible(FALSE);
getChildView("purchase_warning_notenough")->setVisible(FALSE);
getChildView("contacting")->setVisible(FALSE);
getChildView("buy_action")->setVisible(FALSE);
if (hasError)
{
@ -222,8 +238,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
{
if (mHasTarget)
{
getChildView("buy_action")->setVisible( true);
getChild<LLUICtrl>("buy_action")->setTextArg("[ACTION]", mTargetName);
getChild<LLUICtrl>("target_price")->setTextArg("[AMT]", llformat("%d", mTargetPrice));
getChild<LLUICtrl>("required_amount")->setTextArg("[AMT]", llformat("%d", mRequiredAmount));
}
}
@ -244,18 +260,40 @@ void LLFloaterBuyCurrencyUI::updateUI()
if (mHasTarget)
{
if (total >= mTargetPrice)
{
getChildView("purchase_warning_repurchase")->setVisible( true);
}
else
{
getChildView("purchase_warning_notenough")->setVisible( true);
}
getChildView("purchase_warning_repurchase")->setVisible( !getChildView("currency_links")->getVisible());
}
}
getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError);
getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible());
}
void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse)
{
LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price");
if (price_panel->isCollapsed() == collapse)
return;
LLLayoutStack* outer_stack = getChild<LLLayoutStack>("outer_stack");
LLLayoutPanel* required_panel = getChild<LLLayoutPanel>("layout_panel_required");
LLLayoutPanel* msg_panel = getChild<LLLayoutPanel>("layout_panel_msg");
S32 delta_height = price_panel->getRect().getHeight() + required_panel->getRect().getHeight() + msg_panel->getRect().getHeight();
delta_height *= (collapse ? -1 : 1);
LLIconCtrl* icon = getChild<LLIconCtrl>("normal_background");
LLRect rect = icon->getRect();
icon->setRect(rect.setOriginAndSize(rect.mLeft, rect.mBottom - delta_height, rect.getWidth(), rect.getHeight() + delta_height));
outer_stack->collapsePanel(price_panel, collapse);
outer_stack->collapsePanel(required_panel, collapse);
outer_stack->collapsePanel(msg_panel, collapse);
outer_stack->updateLayout();
LLRect floater_rect = getRect();
floater_rect.mBottom -= delta_height;
setShape(floater_rect, false);
}
void LLFloaterBuyCurrencyUI::onClickBuy()
@ -278,25 +316,109 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
LLStatusBar::sendMoneyBalanceRequest();
}
LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL;
// static
void LLFloaterBuyCurrency::buyCurrency()
{
LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
ui->noTarget();
ui->updateUI();
// <FS:Ansariel> OpenSim support
//delete sPropertiesRequest;
//sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
#if OPENSIM
if (LLGridManager::instance().isInOpenSim())
{
LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
ui->noTarget();
ui->updateUI();
}
else
#endif
{
delete sPropertiesRequest;
sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
}
// <FS:Ansariel>
}
// static
void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)
{
LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
// <COLOSI opensim multi-currency support>
// Not wrapping name here because according to llfloaterbuycurrency.h
// name should not include currency symbols as the price will be appended to the string.
// If an "L$" is ever included in a name, then we should call Tea::wrapCurrency on it here.
// </COLOSI opensim multi-currency support>>
ui->target(name, price);
ui->updateUI();
// <FS:Ansariel> OpenSim support
//delete sPropertiesRequest;
//sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
#if OPENSIM
if (LLGridManager::instance().isInOpenSim())
{
LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
// <COLOSI opensim multi-currency support>
// Not wrapping name here because according to llfloaterbuycurrency.h
// name should not include currency symbols as the price will be appended to the string.
// If an "L$" is ever included in a name, then we should call Tea::wrapCurrency on it here.
// </COLOSI opensim multi-currency support>>
ui->target(name, price);
ui->updateUI();
}
else
#endif
{
delete sPropertiesRequest;
sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
}
// <FS:Ansariel>
}
// static
void LLFloaterBuyCurrency::handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price)
{
delete sPropertiesRequest;
sPropertiesRequest = NULL;
if (has_piof)
{
LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
if (has_target)
{
ui->target(name, price);
}
else
{
ui->noTarget();
}
ui->updateUI();
ui->collapsePanels(!has_target);
}
else
{
LLFloaterReg::showInstance("add_payment_method");
}
}
LLFetchAvatarPaymentInfo::LLFetchAvatarPaymentInfo(bool has_target, const std::string& name, S32 price)
: mAvatarID(gAgent.getID()),
mHasTarget(has_target),
mPrice(price),
mName(name)
{
LLAvatarPropertiesProcessor* processor = LLAvatarPropertiesProcessor::getInstance();
// register ourselves as an observer
processor->addObserver(mAvatarID, this);
// send a request (duplicates will be suppressed inside the avatar
// properties processor)
processor->sendAvatarPropertiesRequest(mAvatarID);
}
LLFetchAvatarPaymentInfo::~LLFetchAvatarPaymentInfo()
{
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this);
}
void LLFetchAvatarPaymentInfo::processProperties(void* data, EAvatarProcessorType type)
{
if (data && type == APT_PROPERTIES)
{
LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
LLFloaterBuyCurrency::handleBuyCurrency(LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(avatar_data), mHasTarget, mName, mPrice);
}
}
// <COLOSI opensim multi-currency support>
@ -311,7 +433,8 @@ void LLFloaterBuyCurrency::updateCurrencySymbols()
// update all text boxes with currency symbols.
LLTextBox* tb = NULL;
static const std::list<std::string> sctb = { "info_need_more", "info_buying", "currency_label", "purchase_warning_repurchase", "purchase_warning_notenough" };
static const std::list<std::string> sctb = { "info_need_more", "info_buying", "target_price", "balance_amount",
"required_amount", "currency_label", "total_amount", "purchase_warning_repurchase" };
// Do not include balance_amount and total_amount because they are updated on every display when amounts are replaced.
for (std::list<std::string>::const_iterator iter = sctb.begin(); iter != sctb.end(); ++iter)
{
@ -324,3 +447,4 @@ void LLFloaterBuyCurrency::updateCurrencySymbols()
}
}
// </COLOSI opensim multi-currency support>

View File

@ -27,15 +27,34 @@
#ifndef LL_LLFLOATERBUYCURRENCY_H
#define LL_LLFLOATERBUYCURRENCY_H
#include "llavatarpropertiesprocessor.h"
#include "stdtypes.h"
#include "llagent.h"
class LLFloater;
class LLFetchAvatarPaymentInfo : public LLAvatarPropertiesObserver
{
public:
LLFetchAvatarPaymentInfo(bool has_target, const std::string& name = std::string(), S32 price = 0);
~LLFetchAvatarPaymentInfo();
void processProperties(void* data, EAvatarProcessorType type);
private:
LLUUID mAvatarID;
bool mHasTarget;
std::string mName;
S32 mPrice;
};
class LLFloaterBuyCurrency
{
public:
static void buyCurrency();
static void buyCurrency(const std::string& name, S32 price);
static void handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price);
/* name should be a noun phrase of the object or service being bought:
"That object costs"
"Trying to give"
@ -45,6 +64,8 @@ public:
static LLFloater* buildFloater(const LLSD& key);
static LLFetchAvatarPaymentInfo* sPropertiesRequest;
// <COLOSI opensim multi-currency support>
// Necessary because floater was designed to build only on first display.
// Forces refresh of all currency symbols in floater when called.
@ -52,5 +73,4 @@ public:
// </COLOSI opensim multi-currency support>
};
#endif

View File

@ -0,0 +1,323 @@
/**
* @file llfloatercreatelandmark.cpp
* @brief LLFloaterCreateLandmark class implementation
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatercreatelandmark.h"
#include "llagent.h"
#include "llagentui.h"
#include "llcombobox.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
#include "llnotificationsutil.h"
#include "llpanellandmarkinfo.h"
#include "llparcel.h"
#include "lltextbox.h"
#include "lltexteditor.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
typedef std::pair<LLUUID, std::string> folder_pair_t;
class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
protected:
/*virtual*/ void done()
{
mFloater->setItem(gInventory.getAddedIDs());
}
private:
LLFloaterCreateLandmark* mFloater;
};
LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key)
: LLFloater("add_landmark"),
mItem(NULL)
{
mInventoryObserver = new LLLandmarksInventoryObserver(this);
}
LLFloaterCreateLandmark::~LLFloaterCreateLandmark()
{
removeObserver();
}
BOOL LLFloaterCreateLandmark::postBuild()
{
mFolderCombo = getChild<LLComboBox>("folder_combo");
mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
mNotesEditor = getChild<LLTextEditor>("notes_editor");
getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this));
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
}
void LLFloaterCreateLandmark::removeObserver()
{
if (gInventory.containsObserver(mInventoryObserver))
gInventory.removeObserver(mInventoryObserver);
}
void LLFloaterCreateLandmark::onOpen(const LLSD& key)
{
LLUUID dest_folder = LLUUID();
if (key.has("dest_folder"))
{
dest_folder = key["dest_folder"].asUUID();
}
mItem = NULL;
gInventory.addObserver(mInventoryObserver);
setLandmarkInfo(dest_folder);
populateFoldersList(dest_folder);
}
void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id)
{
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
LLParcel* parcel = parcel_mgr->getAgentParcel();
std::string name = parcel->getName();
LLVector3 agent_pos = gAgent.getPositionAgent();
if (name.empty())
{
S32 region_x = ll_round(agent_pos.mV[VX]);
S32 region_y = ll_round(agent_pos.mV[VY]);
S32 region_z = ll_round(agent_pos.mV[VZ]);
std::string region_name;
LLViewerRegion* region = parcel_mgr->getSelectionRegion();
if (region)
{
region_name = region->getName();
}
else
{
std::string desc;
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
region_name = desc;
}
mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)",
region_name.c_str(), region_x, region_y, region_z));
}
else
{
mLandmarkTitleEditor->setText(name);
}
LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
}
bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
{
return left.second < right.second;
}
void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
{
// Collect all folders that can contain landmarks.
LLInventoryModel::cat_array_t cats;
LLPanelLandmarkInfo::collectLandmarkFolders(cats);
mFolderCombo->removeall();
// Put the "My Favorites" folder first in list.
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
if (!favorites_cat)
{
LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
}
else
{
mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID());
}
// Add the "Landmarks" category.
const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID);
if (!lmcat)
{
LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL;
}
else
{
std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat);
mFolderCombo->add(cat_full_name, lmcat->getUUID());
}
typedef std::vector<folder_pair_t> folder_vec_t;
folder_vec_t folders;
// Sort the folders by their full name.
for (S32 i = 0; i < cats.size(); i++)
{
const LLViewerInventoryCategory* cat = cats.at(i);
std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat);
folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
}
sort(folders.begin(), folders.end(), cmp_folders);
// Finally, populate the combobox.
for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
mFolderCombo->add(it->second, LLSD(it->first));
if (folder_id.notNull())
{
mFolderCombo->setCurrentByID(folder_id);
}
}
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
std::string folder_name = resp["message"].asString();
if (!folder_name.empty())
{
inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1);
gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func);
gInventory.notifyObservers();
}
}
});
}
void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
{
populateFoldersList(folder_id);
}
void LLFloaterCreateLandmark::onSaveClicked()
{
if (mItem.isNull())
{
closeFloater();
return;
}
std::string current_title_value = mLandmarkTitleEditor->getText();
std::string item_title_value = mItem->getName();
std::string current_notes_value = mNotesEditor->getText();
std::string item_notes_value = mItem->getDescription();
LLStringUtil::trim(current_title_value);
LLStringUtil::trim(current_notes_value);
LLUUID item_id = mItem->getUUID();
LLUUID folder_id = mFolderCombo->getValue().asUUID();
bool change_parent = folder_id != mItem->getParentUUID();
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
if (!current_title_value.empty() &&
(item_title_value != current_title_value || item_notes_value != current_notes_value))
{
new_item->rename(current_title_value);
new_item->setDescription(current_notes_value);
LLPointer<LLInventoryCallback> cb;
if (change_parent)
{
cb = new LLUpdateLandmarkParent(new_item, folder_id);
}
LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
gInventory.accountForUpdate(up);
update_inventory_item(new_item, cb);
}
else if (change_parent)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
new_item->setParent(folder_id);
new_item->updateParentOnServer(FALSE);
}
gInventory.updateItem(new_item);
gInventory.notifyObservers();
closeFloater();
}
void LLFloaterCreateLandmark::onCancelClicked()
{
if (!mItem.isNull())
{
LLUUID item_id = mItem->getUUID();
remove_inventory_item(item_id, NULL);
}
closeFloater();
}
void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
for (uuid_set_t::const_iterator item_iter = items.begin();
item_iter != items.end();
++item_iter)
{
const LLUUID& item_id = (*item_iter);
if(!highlight_offered_object(item_id))
{
continue;
}
LLInventoryItem* item = gInventory.getItem(item_id);
llassert(item);
if (item && (LLAssetType::AT_LANDMARK == item->getType()) )
{
if(!getItem())
{
removeObserver();
mItem = item;
break;
}
}
}
}

View File

@ -0,0 +1,74 @@
/**
* @file llfloatercreatelandmark.h
* @brief LLFloaterCreateLandmark class definition
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERCREATELANDMARK_H
#define LL_LLFLOATERCREATELANDMARK_H
#include "llfloater.h"
class LLComboBox;
class LLInventoryItem;
class LLLineEditor;
class LLTextEditor;
class LLLandmarksInventoryObserver;
class LLFloaterCreateLandmark:
public LLFloater
{
friend class LLFloaterReg;
public:
LLFloaterCreateLandmark(const LLSD& key);
~LLFloaterCreateLandmark();
BOOL postBuild();
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
LLInventoryItem* getItem() { return mItem; }
private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
void folderCreatedCallback(LLUUID folder_id);
LLComboBox* mFolderCombo;
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
};
#endif

View File

@ -53,11 +53,15 @@ namespace
const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale");
const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma");
const std::string FIELD_SKY_SUN_ROTATION("sun_rotation");
const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");
const std::string FIELD_SKY_SUN_SCALE("sun_scale");
const std::string FIELD_SKY_GLOW_FOCUS("glow_focus");
const std::string FIELD_SKY_GLOW_SIZE("glow_size");
const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
const std::string BTN_RESET("btn_reset");
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
@ -96,9 +100,13 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()
getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
getChild<LLUICtrl>(BTN_RESET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onButtonReset(); });
getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); });
@ -169,10 +177,25 @@ void LLFloaterEnvironmentAdjust::refresh()
getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R));
getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mLiveSky->getStarBrightness());
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mLiveSky->getSunRotation());
getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mLiveSky->getSunScale());
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mLiveSky->getMoonRotation());
// Sun rotation
LLQuaternion quat = mLiveSky->getSunRotation();
F32 azimuth;
F32 elevation;
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
// Moon rotation
quat = mLiveSky->getMoonRotation();
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
}
@ -325,10 +348,45 @@ void LLFloaterEnvironmentAdjust::onStarBrightnessChanged()
void LLFloaterEnvironmentAdjust::onSunRotationChanged()
{
if (!mLiveSky)
return;
mLiveSky->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation());
mLiveSky->update();
LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
F32 azimuth;
F32 elevation;
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
if (mLiveSky)
{
mLiveSky->setSunRotation(quat);
mLiveSky->update();
}
}
void LLFloaterEnvironmentAdjust::onSunAzimElevChanged()
{
F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
LLQuaternion quat;
azimuth *= DEG_TO_RAD;
elevation *= DEG_TO_RAD;
if (is_approx_zero(elevation))
{
elevation = F_APPROXIMATELY_ZERO;
}
quat.setAngleAxis(-elevation, 0, 1, 0);
LLQuaternion az_quat;
az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
quat *= az_quat;
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
if (mLiveSky)
{
mLiveSky->setSunRotation(quat);
mLiveSky->update();
}
}
void LLFloaterEnvironmentAdjust::onSunScaleChanged()
@ -341,10 +399,45 @@ void LLFloaterEnvironmentAdjust::onSunScaleChanged()
void LLFloaterEnvironmentAdjust::onMoonRotationChanged()
{
if (!mLiveSky)
return;
mLiveSky->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation());
mLiveSky->update();
LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
F32 azimuth;
F32 elevation;
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
if (mLiveSky)
{
mLiveSky->setMoonRotation(quat);
mLiveSky->update();
}
}
void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged()
{
F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
LLQuaternion quat;
azimuth *= DEG_TO_RAD;
elevation *= DEG_TO_RAD;
if (is_approx_zero(elevation))
{
elevation = F_APPROXIMATELY_ZERO;
}
quat.setAngleAxis(-elevation, 0, 1, 0);
LLQuaternion az_quat;
az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
quat *= az_quat;
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
if (mLiveSky)
{
mLiveSky->setMoonRotation(quat);
mLiveSky->update();
}
}
void LLFloaterEnvironmentAdjust::onCloudMapChanged()

View File

@ -73,9 +73,11 @@ private:
void onGlowChanged();
void onStarBrightnessChanged();
void onSunRotationChanged();
void onSunAzimElevChanged();
void onSunScaleChanged();
void onMoonRotationChanged();
void onMoonAzimElevChanged();
void onCloudMapChanged();
void onWaterMapChanged();

View File

@ -128,7 +128,7 @@ void LLFloaterFixedEnvironment::onOpen(const LLSD& key)
updateEditEnvironment();
syncronizeTabs();
refresh();
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
}
@ -180,7 +180,7 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p
updateEditEnvironment();
syncronizeTabs();
refresh();
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST);
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
}
void LLFloaterFixedEnvironment::syncronizeTabs()
@ -460,7 +460,7 @@ void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<
setDirtyFlag();
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater);
setEditSettings(legacywater);
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
}
//=========================================================================
@ -548,7 +548,7 @@ void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std:
setDirtyFlag();
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky);
setEditSettings(legacysky);
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
}
//=========================================================================

View File

@ -26,6 +26,7 @@
#include "llfloater.h"
#include "llmediactrl.h"
#include "llfloaterreg.h"
// register with dispatch via global object
LLFloaterHandler gFloaterHandler;
@ -50,9 +51,15 @@ LLFloater* get_parent_floater(LLView* view)
bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLMediaCtrl *web)
{
if (params.size() < 2) return false;
if (params.size() < 1) return false;
LLFloater* floater = NULL;
// *TODO: implement floater lookup by name
if (params[0].asString() == "destinations")
{
LLFloaterReg::toggleInstanceOrBringToFront("destinations");
return true;
}
if (params[0].asString() == "self")
{
if (web)

View File

@ -0,0 +1,92 @@
/**
* @file llfloaterhowto.cpp
* @brief A variant of web floater meant to open guidebook
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterhowto.h"
#include "llfloaterreg.h"
#include "llviewercontrol.h"
#include "llweb.h"
const S32 STACK_WIDTH = 300;
const S32 STACK_HEIGHT = 505; // content will be 500
LLFloaterHowTo::LLFloaterHowTo(const Params& key) :
LLFloaterWebContent(key)
{
mShowPageTitle = false;
}
BOOL LLFloaterHowTo::postBuild()
{
LLFloaterWebContent::postBuild();
return TRUE;
}
void LLFloaterHowTo::onOpen(const LLSD& key)
{
LLFloaterWebContent::Params p(key);
if (!p.url.isProvided() || p.url.getValue().empty())
{
std::string url = gSavedSettings.getString("GuidebookURL");
p.url = LLWeb::expandURLSubstitutions(url, LLSD());
}
p.show_chrome = false;
LLFloaterWebContent::onOpen(p);
if (p.preferred_media_size().isEmpty())
{
// Elements from LLFloaterWebContent did not pick up restored size (save_rect) of LLFloaterHowTo
// set the stack size and position (alternative to preferred_media_size)
LLLayoutStack *stack = getChild<LLLayoutStack>("stack1");
LLRect stack_rect = stack->getRect();
stack->reshape(STACK_WIDTH, STACK_HEIGHT);
stack->setOrigin(stack_rect.mLeft, stack_rect.mTop - STACK_HEIGHT);
stack->updateLayout();
}
}
LLFloaterHowTo* LLFloaterHowTo::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterHowTo>("guidebook");
}
BOOL LLFloaterHowTo::handleKeyHere(KEY key, MASK mask)
{
BOOL handled = FALSE;
if (KEY_F1 == key )
{
closeFloater();
handled = TRUE;
}
return handled;
}

View File

@ -0,0 +1,58 @@
/**
* @file llfloaterhowto.h
* @brief A variant of web floater meant to open guidebook
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERHOWTO_H
#define LL_LLFLOATERHOWTO_H
#include "llfloaterwebcontent.h"
class LLMediaCtrl;
class LLFloaterHowTo :
public LLFloaterWebContent
{
public:
LOG_CLASS(LLFloaterHowTo);
typedef LLFloaterWebContent::Params Params;
LLFloaterHowTo(const Params& key);
void onOpen(const LLSD& key) override;
BOOL handleKeyHere(KEY key, MASK mask) override;
static LLFloaterHowTo* getInstance();
bool matchesKey(const LLSD& key) override { return true; /*single instance*/ };
private:
BOOL postBuild() override;
};
#endif // LL_LLFLOATERHOWTO_H

View File

@ -69,6 +69,7 @@
#include "llviewerchat.h"
#include "lltranslate.h"
#include "llautoreplace.h"
#include "lluiusage.h"
// [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0b)
#include "rlvactions.h"
#include "rlvcommon.h"
@ -707,6 +708,7 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha
void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
{
LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);

View File

@ -348,6 +348,7 @@ void LLFloaterInspect::refresh()
LLResMgr& res_mgr = LLResMgr::instance();
LLSelectMgr& sel_mgr = LLSelectMgr::instance();
S32 fcount = 0;
S32 fcount_visible = 0;
S32 tcount = 0;
S32 vcount = 0;
S32 objcount = 0;
@ -383,6 +384,7 @@ void LLFloaterInspect::refresh()
LLSelectNode* obj = *iter;
LLSD row;
std::string owner_name, creator_name;
auto vobj{obj->getObject()};
if (obj->mCreationDate == 0)
{ // Don't have valid information from the server, so skip this one
@ -462,12 +464,12 @@ void LLFloaterInspect::refresh()
mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetCreatorNameCallback, this));
}
row["id"] = obj->getObject()->getID();
row["id"] = vobj->getID();
row["columns"][0]["column"] = "object_name";
row["columns"][0]["type"] = "text";
// make sure we're either at the top of the link chain
// or top of the editable chain, for attachments
if(!(obj->getObject()->isRoot() || obj->getObject()->isRootEdit()))
if(!(vobj->isRoot() || vobj->isRootEdit()))
{
row["columns"][0]["value"] = std::string(" ") + obj->mName;
}
@ -495,17 +497,17 @@ void LLFloaterInspect::refresh()
row["columns"][5]["value"] = llformat("%d", timestamp);
// </FS:Ansariel>
// PoundLife - Improved Object Inspect
res_mgr.getIntegerString(format_res_string, obj->getObject()->getNumFaces());
res_mgr.getIntegerString(format_res_string, vobj->getNumFaces());
row["columns"][6]["column"] = "facecount";
row["columns"][6]["type"] = "text";
row["columns"][6]["value"] = format_res_string;
res_mgr.getIntegerString(format_res_string, obj->getObject()->getNumVertices());
res_mgr.getIntegerString(format_res_string, vobj->getNumVertices());
row["columns"][7]["column"] = "vertexcount";
row["columns"][7]["type"] = "text";
row["columns"][7]["value"] = format_res_string;
res_mgr.getIntegerString(format_res_string, obj->getObject()->getNumIndices() / 3);
res_mgr.getIntegerString(format_res_string, vobj->getNumIndices() / 3);
row["columns"][8]["column"] = "trianglecount";
row["columns"][8]["type"] = "text";
row["columns"][8]["value"] = format_res_string;
@ -513,7 +515,7 @@ void LLFloaterInspect::refresh()
// Poundlife - Get VRAM
U32 texture_memory = 0;
U32 vram_memory = 0;
getObjectTextureMemory(obj->getObject(), texture_memory, vram_memory);
getObjectTextureMemory(vobj, texture_memory, vram_memory);
res_mgr.getIntegerString(format_res_string, texture_memory / 1024);
row["columns"][9]["column"] = "tramcount";
row["columns"][9]["type"] = "text";
@ -526,15 +528,15 @@ void LLFloaterInspect::refresh()
row["columns"][11]["column"] = "facecount_sort";
row["columns"][11]["type"] = "text";
row["columns"][11]["value"] = LLSD::Integer(obj->getObject()->getNumFaces());
row["columns"][11]["value"] = LLSD::Integer(vobj->getNumFaces());
row["columns"][12]["column"] = "vertexcount_sort";
row["columns"][12]["type"] = "text";
row["columns"][12]["value"] = LLSD::Integer(obj->getObject()->getNumVertices());
row["columns"][12]["value"] = LLSD::Integer(vobj->getNumVertices());
row["columns"][13]["column"] = "trianglecount_sort";
row["columns"][13]["type"] = "text";
row["columns"][13]["value"] = LLSD::Integer(obj->getObject()->getNumIndices() / 3);
row["columns"][13]["value"] = LLSD::Integer(vobj->getNumIndices() / 3);
row["columns"][14]["column"] = "tramcount_sort";
row["columns"][14]["type"] = "text";
@ -546,9 +548,11 @@ void LLFloaterInspect::refresh()
primcount = sel_mgr.getSelection()->getObjectCount();
objcount = sel_mgr.getSelection()->getRootObjectCount();
fcount += obj->getObject()->getNumFaces();
tcount += obj->getObject()->getNumIndices() / 3;
vcount += obj->getObject()->getNumVertices();
fcount += vobj->getNumFaces();
fcount_visible += vobj->getNumVisibleFaces();
tcount += vobj->getNumIndices() / 3;
vcount += vobj->getNumVertices();
// PoundLife - END
mObjectList->addElement(row, ADD_TOP);
}
@ -613,6 +617,8 @@ void LLFloaterInspect::refresh()
args["NUM_OBJECTS"] = format_res_string;
res_mgr.getIntegerString(format_res_string, primcount);
args["NUM_PRIMS"] = format_res_string;
res_mgr.getIntegerString(format_res_string, fcount_visible);
args["NUM_VISIBLE_FACES"] = format_res_string;
res_mgr.getIntegerString(format_res_string, fcount);
args["NUM_FACES"] = format_res_string;
res_mgr.getIntegerString(format_res_string, vcount);

View File

@ -51,6 +51,9 @@
#include "llgroupactions.h"
const std::string LINDEN_HOMES_SKU = "131";
bool LLFloaterLandHoldings::sHasLindenHome = false;
// protected
LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key)
: LLFloater(key),
@ -148,10 +151,24 @@ void LLFloaterLandHoldings::refresh()
void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
{
LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings");
// Is this packet from an old, closed window?
S32 count = msg->getNumberOfBlocks("QueryData");
std::string land_sku;
sHasLindenHome = false;
if (!self)
{
for (S32 i = 0; i < count; i++)
{
if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 )
{
msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
if (LINDEN_HOMES_SKU == land_sku)
{
sHasLindenHome = true;
return;
}
}
}
return;
}
@ -174,12 +191,9 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
F32 global_x;
F32 global_y;
std::string sim_name;
std::string land_sku;
std::string land_type;
S32 i;
S32 count = msg->getNumberOfBlocks("QueryData");
for (i = 0; i < count; i++)
for (S32 i = 0; i < count; i++)
{
msg->getUUID("QueryData", "OwnerID", owner_id, i);
msg->getString("QueryData", "Name", name, i);
@ -196,6 +210,10 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
LL_INFOS() << "Land sku: " << land_sku << LL_ENDL;
land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
if (LINDEN_HOMES_SKU == land_sku)
{
sHasLindenHome = true;
}
}
else
{

View File

@ -57,6 +57,8 @@ public:
static void onGrantList(void* data);
static bool sHasLindenHome;
protected:
void refreshAggregates();

View File

@ -1142,7 +1142,7 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
// <FS:Beq> FIRE-30963 Support pre-defined physics shapes (initially cube)
// S32 which_lod = num_lods - which_mode;
// sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
if(which_mode >= num_lods)
if(which_mode > num_lods)
{
// which_mode is between the last LOD entry and file selection
// so it is a preset

View File

@ -701,7 +701,7 @@ void LLFloaterWorldMap::processParcelInfo(const LLParcelData& parcel_data, const
LLTracker::trackLocation(pos_global, parcel_data.name.empty() ? getString("UnnamedParcel") : parcel_data.name, full_name);
}
void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global)
void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global, const LLVector3d& region_origin)
{
if (pos_global == mRequestedGlobalPos)
{
@ -713,16 +713,8 @@ void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global)
{
return;
}
// <FS:Beq> VarRegion slurl shenanigans
// agent_x = ll_round(region_pos.mV[VX]);
// agent_y = ll_round(region_pos.mV[VY]);
// agent_z = ll_round(region_pos.mV[VZ]);
// LLVector3 pos_region((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
// (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
// (F32)pos_global.mdV[VZ]);
auto region_origin = region->getOriginGlobal();
auto pos_region = LLVector3(pos_global - region_origin);
// </FS:Beq>
LLSD body;
std::string url = region->getCapability("RemoteParcelRequest");
@ -739,7 +731,6 @@ void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global)
region->getRegionID(), pos_region, pos_global,
mParcelInfoObserver->getObserverHandle() );
}
else
{
@ -903,7 +894,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
{
mShowParcelInfo = true;
requestParcelInfo(pos_global);
requestParcelInfo(pos_global, sim_info->getGlobalOrigin());
}
else
{

View File

@ -179,7 +179,7 @@ protected:
void cacheLandmarkPosition();
// <FS:Ansariel> Parcel details on map
void requestParcelInfo(const LLVector3d& pos_global);
void requestParcelInfo(const LLVector3d& pos_global, const LLVector3d& region_origin);
LLVector3d mRequestedGlobalPos;
bool mShowParcelInfo;
FSWorldMapParcelInfoObserver* mParcelInfoObserver;

View File

@ -1,5 +1,5 @@
/**
* @file llsaveoutfitcombobtn.h
* @file llflyoutcombobtn.h
* @brief Represents outfit save/save as combo button.
*
* $LicenseInfo:firstyear=2010&license=viewerlgpl$

View File

@ -45,6 +45,7 @@ public:
virtual LLFolderType::EType getPreferredType() const = 0;
virtual void showProperties(void) = 0;
virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
virtual BOOL isAgentInventory() const { return FALSE; }
virtual BOOL isUpToDate() const = 0;
virtual bool hasChildren() const = 0;
virtual LLInventoryType::EType getInventoryType() const = 0;

View File

@ -2046,31 +2046,11 @@ void LLItemBridge::restoreToWorld()
void LLItemBridge::gotoItem()
{
LLInventoryObject *obj = getInventoryObject();
if (obj && obj->getIsLinkType())
{
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
// <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
//if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id))
if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id) && !gSavedSettings.getBOOL("FSShowInboxFolder"))
// </FS:Ansariel>
{
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory && sidepanel_inventory->getInboxPanel())
{
sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
}
}
else
{
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
if (active_panel)
{
active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
}
}
}
LLInventoryObject *obj = getInventoryObject();
if (obj && obj->getIsLinkType())
{
show_item_original(obj->getUUID());
}
}
LLUIImagePtr LLItemBridge::getIcon() const
@ -4523,6 +4503,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("New Body Parts"));
items.push_back(std::string("New Settings"));
items.push_back(std::string("upload_def"));
if (!LLEnvironment::instance().isInventoryEnabled())
{
disabled_items.push_back("New Settings");
}
}
}
getClipboardEntries(false, items, disabled_items, flags);
@ -7844,7 +7830,8 @@ void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action
return;
LLUUID asset_id = item->getAssetUUID();
// FIRE-30701 - Allow crossfade time to apply when using EEP from inventory.
// LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
//LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id, LLEnvironment::TRANSITION_INSTANT);
//LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
}
@ -8018,21 +8005,17 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti
}
void LLLinkFolderBridge::gotoItem()
{
const LLUUID &cat_uuid = getFolderID();
if (!cat_uuid.isNull())
{
LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
if (base_folder)
{
if (LLInventoryModel* model = getInventoryModel())
{
model->fetchDescendentsOf(cat_uuid);
}
base_folder->setOpen(TRUE);
mRoot->setSelection(base_folder,TRUE);
mRoot->scrollToShowSelection();
}
}
LLItemBridge::gotoItem();
const LLUUID &cat_uuid = getFolderID();
if (!cat_uuid.isNull())
{
LLFolderViewItem *base_folder = LLInventoryPanel::getActiveInventoryPanel()->getItemByID(cat_uuid);
if (base_folder)
{
base_folder->setOpen(TRUE);
}
}
}
const LLUUID &LLLinkFolderBridge::getFolderID() const
{

View File

@ -69,7 +69,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
mPermissions(p.permissions),
mFilterTypes(p.types),
mFilterUUID(p.uuid),
mFilterLinks(p.links)
mFilterLinks(p.links),
mSearchVisibility(p.search_visibility)
{
}
@ -171,6 +172,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
passed = passed && checkAgainstPermissions(listener);
passed = passed && checkAgainstFilterLinks(listener);
passed = passed && checkAgainstCreator(listener);
passed = passed && checkAgainstSearchVisibility(listener);
return passed;
}
@ -625,6 +627,27 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
}
}
bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItemInventory* listener) const
{
if (!listener || !hasFilterString()) return TRUE;
const LLUUID object_id = listener->getUUID();
const LLInventoryObject *object = gInventory.getObject(object_id);
if (!object) return TRUE;
const BOOL is_link = object->getIsLinkType();
if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0))
return FALSE;
if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0))
return FALSE;
if (!listener->isAgentInventory() && ((mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY) == 0))
return FALSE;
return TRUE;
}
const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
{
return mFilterSubString;
@ -796,6 +819,61 @@ void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_list
}
}
void LLInventoryFilter::toggleSearchVisibilityLinks()
{
bool hide_links = mFilterOps.mSearchVisibility & VISIBILITY_LINKS;
if (hide_links)
{
mFilterOps.mSearchVisibility &= ~VISIBILITY_LINKS;
}
else
{
mFilterOps.mSearchVisibility |= VISIBILITY_LINKS;
}
if (hasFilterString())
{
setModified(hide_links ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
}
}
void LLInventoryFilter::toggleSearchVisibilityTrash()
{
bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH;
if (hide_trash)
{
mFilterOps.mSearchVisibility &= ~VISIBILITY_TRASH;
}
else
{
mFilterOps.mSearchVisibility |= VISIBILITY_TRASH;
}
if (hasFilterString())
{
setModified(hide_trash ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
}
}
void LLInventoryFilter::toggleSearchVisibilityLibrary()
{
bool hide_library = mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY;
if (hide_library)
{
mFilterOps.mSearchVisibility &= ~VISIBILITY_LIBRARY;
}
else
{
mFilterOps.mSearchVisibility |= VISIBILITY_LIBRARY;
}
if (hasFilterString())
{
setModified(hide_library ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
}
}
void LLInventoryFilter::setFilterNoMarketplaceFolder()
{
mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS;
@ -919,6 +997,44 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
}
}
void LLInventoryFilter::setSearchVisibilityTypes(U32 types)
{
if (mFilterOps.mSearchVisibility != types)
{
// keep current items only if no perm bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mSearchVisibility & ~types);
BOOL more_bits_set = (~mFilterOps.mSearchVisibility & types);
mFilterOps.mSearchVisibility = types;
if (more_bits_set && fewer_bits_set)
{
setModified(FILTER_RESTART);
}
else if (more_bits_set)
{
// target must have all requested permission bits, so more bits == more restrictive
setModified(FILTER_MORE_RESTRICTIVE);
}
else if (fewer_bits_set)
{
setModified(FILTER_LESS_RESTRICTIVE);
}
}
}
void LLInventoryFilter::setSearchVisibilityTypes(const Params& params)
{
if (!params.validateBlock())
{
return;
}
if (params.filter_ops.search_visibility.isProvided())
{
setSearchVisibilityTypes(params.filter_ops.search_visibility);
}
}
void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
{
if (mFilterOps.mPermissions != perms)
@ -1346,6 +1462,18 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_SETTINGS))
{
filtered_types += LLTrans::getString("Settings");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
not_filtered_types += LLTrans::getString("Settings");
filtered_by_all_types = FALSE;
}
if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
&& filtered_by_type
&& !filtered_by_all_types)
@ -1437,6 +1565,7 @@ void LLInventoryFilter::toParams(Params& params) const
params.filter_ops.show_folder_state = getShowFolderState();
params.filter_ops.creator_type = getFilterCreatorType();
params.filter_ops.permissions = getFilterPermissions();
params.filter_ops.search_visibility = getSearchVisibilityTypes();
params.substring = getFilterSubString();
params.since_logoff = isSinceLogoff();
}
@ -1458,6 +1587,7 @@ void LLInventoryFilter::fromParams(const Params& params)
//setFilterCreator(params.filter_ops.creator_type);
//setShowFolderState(params.filter_ops.show_folder_state);
//setFilterPermissions(params.filter_ops.permissions);
//setSearchVisibilityTypes(params.filter_ops.search_visibility);
//setFilterSubString(params.substring);
//setDateRangeLastLogoff(params.since_logoff);
if (params.filter_ops.types.isProvided())
@ -1496,6 +1626,10 @@ void LLInventoryFilter::fromParams(const Params& params)
{
setFilterPermissions(params.filter_ops.permissions);
}
if (params.filter_ops.search_visibility.isProvided())
{
setSearchVisibilityTypes(params.filter_ops.search_visibility);
}
// <FS:Ansariel> FIRE-8947: Don't restore filter string on relog
//if (params.substring.isProvided())
//{
@ -1533,6 +1667,11 @@ U64 LLInventoryFilter::getFilterSettingsTypes() const
return mFilterOps.mFilterSettingsTypes;
}
U64 LLInventoryFilter::getSearchVisibilityTypes() const
{
return mFilterOps.mSearchVisibility;
}
bool LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;

View File

@ -100,6 +100,14 @@ public:
FILTERCREATOR_OTHERS
};
enum ESearchVisibility
{
VISIBILITY_NONE = 0,
VISIBILITY_TRASH = 0x1 << 0,
VISIBILITY_LIBRARY = 0x1 << 1,
VISIBILITY_LINKS = 0x1 << 2
};
struct FilterOps
{
struct DateRange : public LLInitParam::Block<DateRange>
@ -117,11 +125,13 @@ public:
struct Params : public LLInitParam::Block<Params>
{
Optional<U32> types;
Optional<U32> types,
search_visibility;
Optional<U64> object_types,
wearable_types,
settings_types,
category_types;
Optional<EFilterLink> links;
Optional<LLUUID> uuid;
Optional<DateRange> date_range;
@ -138,6 +148,7 @@ public:
settings_types("settings_types", 0xffffFFFFffffFFFFULL),
category_types("category_types", 0xffffFFFFffffFFFFULL),
links("links", FILTERLINK_INCLUDE_LINKS),
search_visibility("search_visibility", 0xFFFFFFFF),
uuid("uuid"),
date_range("date_range"),
hours_ago("hours_ago", 0),
@ -150,7 +161,8 @@ public:
FilterOps(const Params& = Params());
U32 mFilterTypes;
U32 mFilterTypes,
mSearchVisibility;
U64 mFilterObjectTypes, // For _OBJECT
mFilterWearableTypes,
mFilterSettingsTypes, // for _SETTINGS
@ -194,7 +206,8 @@ public:
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
U64 getFilterWearableTypes() const;
U64 getFilterSettingsTypes() const;
U64 getFilterSettingsTypes() const;
U64 getSearchVisibilityTypes() const;
bool isFilterObjectTypesWith(LLInventoryType::EType t) const;
void setFilterObjectTypes(U64 types);
@ -215,6 +228,12 @@ public:
ESearchType getSearchType() { return mSearchType; }
void setFilterCreator(EFilterCreatorType type);
void toggleSearchVisibilityLinks();
void toggleSearchVisibilityTrash();
void toggleSearchVisibilityLibrary();
void setSearchVisibilityTypes(U32 types);
void setSearchVisibilityTypes(const Params& params);
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
@ -323,6 +342,7 @@ private:
bool checkAgainstPermissions(const LLInventoryItem* item) const;
bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
bool checkAgainstCreator(const class LLFolderViewModelItemInventory* listener) const;
bool checkAgainstSearchVisibility(const class LLFolderViewModelItemInventory* listener) const;
bool checkAgainstClipboard(const LLUUID& object_id) const;
FilterOps mFilterOps;

View File

@ -885,69 +885,48 @@ void show_item_profile(const LLUUID& item_uuid)
void show_item_original(const LLUUID& item_uuid)
{
// <FS:Ansariel> FIRE-19493: "Show Original" should open main inventory panel
//LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
//if (!floater_inventory)
//{
// LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
// return;
//}
LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
if (!floater_inventory)
{
LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
return;
}
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory)
{
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
if (main_inventory)
{
main_inventory->resetFilters();
}
reset_inventory_filter();
////sidetray inventory panel
//LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (!LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("inventory")->isInVisibleChain())
{
LLFloaterReg::toggleInstanceOrBringToFront("inventory");
}
//bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain();
//LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
//if (!active_panel)
//{
// //this may happen when there is no floatera and other panel is active in inventory tab
// if (sidepanel_inventory)
// {
// sidepanel_inventory->showInventoryPanel();
// }
//}
//
//active_panel = LLInventoryPanel::getActiveInventoryPanel();
//if (!active_panel)
//{
// return;
//}
//active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
//
//if(do_reset_inventory_filter)
//{
// reset_inventory_filter();
//}
LLFloaterReg::showInstance("inventory");
LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
sidepanel_inventory->showInventoryPanel();
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
main_inventory->showAllItemsPanel();
main_inventory->resetFilters();
main_inventory->onFilterEdit("");
LLUUID linked_item_id = gInventory.getLinkedItemID(item_uuid);
bool in_inbox = (gInventory.isObjectDescendentOf(linked_item_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
bool show_inbox = gSavedSettings.getBOOL("FSShowInboxFolder"); // <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
if (in_inbox && !show_inbox)
{
LLInventoryPanel * inventory_panel = NULL;
sidepanel_inventory->openInbox();
inventory_panel = sidepanel_inventory->getInboxPanel();
if (inventory_panel)
{
inventory_panel->setSelection(linked_item_id, TAKE_FOCUS_YES);
}
}
else
{
main_inventory->getActivePanel()->setSelection(linked_item_id, TAKE_FOCUS_YES);
}
// </FS:Ansariel>
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
// <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
// if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id))
if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id) && !gSavedSettings.getBOOL("FSShowInboxFolder"))
// </FS:Ansariel>
{
if (sidepanel_inventory->getInboxPanel())
{
sidepanel_inventory->openInbox();
sidepanel_inventory->getInboxPanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
}
}
else
{
sidepanel_inventory->selectAllItemsPanel();
if (sidepanel_inventory->getActivePanel())
{
sidepanel_inventory->getActivePanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
}
}
}
}
@ -1986,6 +1965,26 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
return result && !has_bad_items;
}
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
{
LLInventoryItem* inv_item = gInventory.getItem(item_id);
if (inv_item)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
new_item->setParent(new_parent_id);
new_item->updateParentOnServer(FALSE);
gInventory.updateItem(new_item);
gInventory.notifyObservers();
}
}
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------

View File

@ -99,6 +99,8 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid);
LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
/** Miscellaneous global functions
** **
*******************************************************************************/

View File

@ -165,7 +165,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mViewsInitialized(VIEWS_UNINITIALIZED),
mInvFVBridgeBuilder(NULL),
mInventoryViewModel(p.name),
mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
mGroupedItemBridge(new LLFolderViewGroupedItemBridge),
mFocusSelection(false)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@ -1338,6 +1339,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
void LLInventoryPanel::clearSelection()
{
mSelectThisID.setNull();
mFocusSelection = false;
}
LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const
@ -1917,15 +1919,17 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus )
{
LLFolderViewItem* itemp = getItemByID(obj_id);
if(itemp && itemp->getViewModelItem())
if(itemp && itemp->getViewModelItem() && itemp->passedFilter())
{
itemp->arrangeAndSet(TRUE, take_keyboard_focus);
mSelectThisID.setNull();
mFocusSelection = false;
return;
}
else
{
// save the desired item to be selected later (if/when ready)
mFocusSelection = take_keyboard_focus;
mSelectThisID = obj_id;
}
}
@ -1934,7 +1938,7 @@ void LLInventoryPanel::updateSelection()
{
if (mSelectThisID.notNull())
{
setSelectionByID(mSelectThisID, false);
setSelectionByID(mSelectThisID, mFocusSelection);
}
}

View File

@ -281,6 +281,7 @@ protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
bool mFocusSelection;
bool mAcceptsDragAndDrop;
bool mAllowMultiSelect;
bool mAllowDrag;
@ -379,27 +380,6 @@ private:
EViewsInitializationState mViewsInitialized; // Whether 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 */

View File

@ -228,23 +228,6 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
}
bool LLLandmarkActions::canCreateLandmarkHere()
{
LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if(!agent_parcel)
{
LL_WARNS() << "No agent region" << LL_ENDL;
return false;
}
if (agent_parcel->getAllowLandmark()
|| LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
{
return true;
}
return false;
}
void LLLandmarkActions::createLandmarkHere(
const std::string& name,
const std::string& desc,
@ -261,11 +244,6 @@ void LLLandmarkActions::createLandmarkHere(
LL_WARNS() << "No agent parcel" << LL_ENDL;
return;
}
if (!canCreateLandmarkHere())
{
LLNotificationsUtil::add("CannotCreateLandmarkNotOwner");
return;
}
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, LLTransactionID::tnull,

View File

@ -72,12 +72,6 @@ public:
*/
static LLViewerInventoryItem* findLandmarkForAgentPos();
/**
* @brief Checks whether agent has rights to create landmark for current parcel.
*/
static bool canCreateLandmarkHere();
/**
* @brief Creates landmark for current parcel.
*/

View File

@ -44,6 +44,7 @@
// newview includes
#include "llagent.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
@ -695,10 +696,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked()
}
else
{
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
}
}
@ -1225,10 +1223,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
if(!landmark)
{
// <FS:Ansariel> FIRE-817: Separate place details floater
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "create_landmark"));
// </FS:Ansariel>
LLFloaterReg::showInstance("add_landmark");
}
else
{

View File

@ -105,7 +105,10 @@ void LLManipRotate::handleSelect()
{
// *FIX: put this in mouseDown?
LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
gFloaterTools->setStatusText("rotate");
if (gFloaterTools)
{
gFloaterTools->setStatusText("rotate");
}
LLManip::handleSelect();
}

View File

@ -182,7 +182,10 @@ void LLManipScale::handleSelect()
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
updateSnapGuides(bbox);
LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
gFloaterTools->setStatusText("scale");
if (gFloaterTools)
{
gFloaterTools->setStatusText("scale");
}
LLManip::handleSelect();
}

View File

@ -291,7 +291,10 @@ LLManipTranslate::~LLManipTranslate()
void LLManipTranslate::handleSelect()
{
LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
gFloaterTools->setStatusText("move");
if (gFloaterTools)
{
gFloaterTools->setStatusText("move");
}
LLManip::handleSelect();
}

View File

@ -477,7 +477,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
std::istringstream content_stream(content_string);
LLSD response_data;
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
// <FS:Beq pp Rye> Use new variant unzip_llsd
// U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
// </FS:Beq pp Rye>
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;

View File

@ -78,6 +78,10 @@
#include "llfloaterreg.h"
#include "boost/lexical_cast.hpp"
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
// </FS:Beq pp Rye>
#ifndef LL_WINDOWS
#include "netdb.h"
@ -1901,27 +1905,35 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
U32 header_size = 0;
if (data_size > 0)
{
std::istringstream stream;
try
{
std::string res_str((char*)data, data_size);
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
// std::istringstream stream;
// try
// {
// std::string res_str((char*)data, data_size);
std::string deprecated_header("<? LLSD/Binary ?>");
// std::string deprecated_header("<? LLSD/Binary ?>");
if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
{
res_str = res_str.substr(deprecated_header.size() + 1, data_size);
header_size = deprecated_header.size() + 1;
}
data_size = res_str.size();
// if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
// {
// res_str = res_str.substr(deprecated_header.size() + 1, data_size);
// header_size = deprecated_header.size() + 1;
// }
// data_size = res_str.size();
stream.str(res_str);
}
catch (std::bad_alloc&)
{
// out of memory, we won't be able to process this mesh
return MESH_OUT_OF_MEMORY;
}
// stream.str(res_str);
// }
// catch (std::bad_alloc&)
// {
// // out of memory, we won't be able to process this mesh
// return MESH_OUT_OF_MEMORY;
// }
U32 dsize = data_size;
char* result_ptr = strip_deprecated_header((char*)data, dsize, &header_size);
data_size = dsize;
boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size);
// </FS:Beq pp Rye>
if (!LLSDSerialize::fromBinary(header, stream, data_size))
{
@ -1990,19 +2002,22 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
}
LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
std::istringstream stream;
try
{
std::string mesh_string((char*)data, data_size);
stream.str(mesh_string);
}
catch (std::bad_alloc&)
{
// out of memory, we won't be able to process this mesh
return MESH_OUT_OF_MEMORY;
}
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
// std::istringstream stream;
// try
// {
// std::string mesh_string((char*)data, data_size);
// stream.str(mesh_string);
// }
// catch (std::bad_alloc&)
// {
// // out of memory, we won't be able to process this mesh
// return MESH_OUT_OF_MEMORY;
// }
if (volume->unpackVolumeFaces(stream, data_size))
// if (volume->unpackVolumeFaces(stream, data_size))
if (volume->unpackVolumeFaces(data, data_size))
// </FS:Beq pp Rye>
{
if (volume->getNumFaces() > 0)
{
@ -2032,10 +2047,13 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
{
try
{
std::string res_str((char*)data, data_size);
std::istringstream stream(res_str);
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
// std::string res_str((char*)data, data_size);
// std::istringstream stream(res_str);
U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
// U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
U32 uzip_result = LLUZipHelper::unzip_llsd(skin, data, data_size);
// </FS:Beq pp Rye>
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id
@ -2073,10 +2091,13 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
{
try
{
std::string res_str((char*)data, data_size);
std::istringstream stream(res_str);
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
// std::string res_str((char*)data, data_size);
// std::istringstream stream(res_str);
U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
// U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, data, data_size);
// <FS:Beq pp Rye>
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id
@ -2085,7 +2106,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
return false;
}
}
catch (std::bad_alloc&)
catch (const std::bad_alloc&) // <FS:Beq pp Rye/> const cos const!
{
LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
return false;
@ -2122,20 +2143,22 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
LLPointer<LLVolume> volume = new LLVolume(volume_params,0);
std::istringstream stream;
try
{
std::string mesh_string((char*)data, data_size);
stream.str(mesh_string);
}
catch (std::bad_alloc&)
{
// out of memory, we won't be able to process this mesh
delete d;
return MESH_OUT_OF_MEMORY;
}
// <FS:Beq pp Rye> Reduce temporaries and copes in decoding mesh headers
// std::istringstream stream;
// try
// {
// std::string mesh_string((char*)data, data_size);
// stream.str(mesh_string);
// }
// catch (std::bad_alloc&)
// {
// // out of memory, we won't be able to process this mesh
// delete d;
// return MESH_OUT_OF_MEMORY;
// }
if (volume->unpackVolumeFaces(stream, data_size))
// if (volume->unpackVolumeFaces(stream, data_size))
if (volume->unpackVolumeFaces(data, data_size))
{
//load volume faces into decomposition buffer
S32 vertex_count = 0;

View File

@ -378,14 +378,14 @@ bool LLModelPreview::matchMaterialOrder(LLModel* lod, LLModel* ref, int& refFace
//1. ref = a,b,c lod1 = d,e => This is not permitted
//2. ref = a,b,c lod1 = c => This would be permitted
LL_INFOS("MESHSKININFO") << "In matchMaterialOrder." << LL_ENDL;
LL_DEBUGS("MESHSKININFO") << "In matchMaterialOrder." << LL_ENDL;
bool isASubset = lod->isMaterialListSubset( ref );
if ( !isASubset )
{
LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
LL_DEBUGS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
std::ostringstream out;
out << "LOD model " << lod->getName() << "'s materials are not a subset of the High LOD (reference) model " << ref->getName();
LL_INFOS() << out.str() << LL_ENDL;
LL_DEBUGS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
return false;
}
@ -471,7 +471,7 @@ bool LLModelPreview::matchMaterialOrder(LLModel* lod, LLModel* ref, int& refFace
// if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match
if ( reorder )
{
LL_INFOS("MESHSKININFO") << "re-ordering." << LL_ENDL;
LL_DEBUGS("MESHSKININFO") << "re-ordering." << LL_ENDL;
lod->sortVolumeFacesByMaterialName();
lod->mMaterialList = ref->mMaterialList;
}
@ -3002,14 +3002,33 @@ void LLModelPreview::lookupLODModelFiles(S32 lod)
S32 next_lod = (lod - 1 >= LLModel::LOD_IMPOSTOR) ? lod - 1 : LLModel::LOD_PHYSICS;
std::string lod_filename = mLODFile[LLModel::LOD_HIGH];
std::string ext = ".dae";
std::string::size_type i = lod_filename.rfind(ext);
if (i != std::string::npos)
// <FS:Beq> BUG-230890 fix case-sensitive filename handling
// std::string ext = ".dae";
// std::string::size_type i = lod_filename.rfind(ext);
// if (i != std::string::npos)
// {
// lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext);
// }
// Note: we cannot use gDirUtilp here because the getExtension forces a tolower which would then break uppercase extensions on Linux/Mac
std::size_t offset = lod_filename.find_last_of('.');
std::string ext = (offset == std::string::npos || offset == 0) ? "" : lod_filename.substr(offset+1);
lod_filename = gDirUtilp->getDirName(lod_filename) + gDirUtilp->getDirDelimiter() + gDirUtilp->getBaseFileName(lod_filename, true) + getLodSuffix(next_lod) + "." + ext;
std::ostringstream out;
out << "Looking for file: " << lod_filename << " for LOD " << next_lod;
LL_DEBUGS("MeshUpload") << out.str() << LL_ENDL;
if(mImporterDebug)
{
lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext);
LLFloaterModelPreview::addStringToLog(out, true);
}
out.str("");
// </FS:Beq>
if (gDirUtilp->fileExists(lod_filename))
{
// <FS:Beq> extra logging is helpful here, so add to log tab
out << "Auto Loading LOD" << next_lod << " from " << lod_filename;
LL_INFOS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
// </FS:Beq>
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
if (fmp)
{

View File

@ -787,7 +787,20 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_MuteData);
msg->addU32Fast(_PREHASH_MuteCRC, crc.getCRC());
gAgent.sendReliableMessage();
if (gDisconnected)
{
LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
return;
}
if (!gAgent.getRegion())
{
LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
return;
}
// Double amount of retries due to this request happening during busy stage
// Ideally this should be turned into a capability
gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
}
//-----------------------------------------------------------------------------

View File

@ -59,6 +59,7 @@
#include "llweb.h"
#include "llhints.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
@ -312,6 +313,7 @@ void LLNavigationBar::setupPanel()
// mBtnBack = getChild<LLPullButton>("back_btn");
// mBtnForward = getChild<LLPullButton>("forward_btn");
// mBtnHome = getChild<LLButton>("home_btn");
// mBtnLandmarks = getChild<LLButton>("landmarks_btn");
// mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
@ -320,6 +322,7 @@ void LLNavigationBar::setupPanel()
mBtnBack = mView->getChild<LLPullButton>("back_btn");
mBtnForward = mView->getChild<LLPullButton>("forward_btn");
mBtnHome = mView->getChild<LLButton>("home_btn");
//mBtnLandmarks = mView->getChild<LLButton>("landmarks_btn"); // <FS:Ansariel> We don't use that right now...
mCmbLocation = mView->getChild<LLLocationInputCtrl>("location_combo");
mSearchComboBox = mView->getChild<LLSearchComboBox>("search_combo_box");
@ -350,6 +353,8 @@ void LLNavigationBar::setupPanel()
//mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this, _1));
//mBtnLandmarks->setClickedCallback(boost::bind(&LLNavigationBar::onLandmarksButtonClicked, this)); // <FS:Ansariel> We don't use that right now...
mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
mSearchComboBox->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
@ -490,6 +495,12 @@ void LLNavigationBar::onHomeButtonClicked(LLUICtrl* ctrl)
gFocusMgr.releaseFocusIfNeeded(ctrl); // [FS:CR] FIRE-12333
}
void LLNavigationBar::onLandmarksButtonClicked()
{
LLFloaterReg::toggleInstanceOrBringToFront("places");
LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_landmark_tab"));
}
void LLNavigationBar::onSearchCommit()
{
std::string search_query = mSearchComboBox->getSimple();

View File

@ -137,6 +137,7 @@ private:
//void onHomeButtonClicked();
void onForwardButtonClicked(LLUICtrl* ctrl);
void onHomeButtonClicked(LLUICtrl* ctrl);
void onLandmarksButtonClicked();
void onLocationSelection();
void onLocationPrearrange(const LLSD& data);
void onSearchCommit();
@ -173,6 +174,7 @@ private:
LLPullButton* mBtnBack;
LLPullButton* mBtnForward;
LLButton* mBtnHome;
LLButton* mBtnLandmarks;
LLSearchComboBox* mSearchComboBox;
LLLocationInputCtrl* mCmbLocation;
// <FS:Zi> No size calculations in code please. XUI handles it all now with visibility_control

View File

@ -69,11 +69,15 @@ namespace
const std::string FIELD_SKY_GLOW_SIZE("glow_size");
const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
const std::string FIELD_SKY_SUN_ROTATION("sun_rotation");
const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");
const std::string FIELD_SKY_SUN_IMAGE("sun_image");
const std::string FIELD_SKY_SUN_SCALE("sun_scale");
const std::string FIELD_SKY_SUN_BEACON("sunbeacon");
const std::string FIELD_SKY_MOON_BEACON("moonbeacon");
const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
const std::string FIELD_SKY_MOON_IMAGE("moon_image");
const std::string FIELD_SKY_MOON_SCALE("moon_scale");
const std::string FIELD_SKY_MOON_BRIGHTNESS("moon_brightness");
@ -473,12 +477,16 @@ BOOL LLPanelSettingsSkySunMoonTab::postBuild()
getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); });
getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetBlankSunTextureId());
getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetBlankSunTextureId());
getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowNoTexture(TRUE);
getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); });
getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
@ -537,13 +545,29 @@ void LLPanelSettingsSkySunMoonTab::refresh()
getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness());
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation());
getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId());
getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale());
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation());
getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId());
getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale());
getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setValue(mSkySettings->getMoonBrightness());
// Sun rotation values
F32 azimuth, elevation;
LLQuaternion quat = mSkySettings->getSunRotation();
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
// Moon rotation values
quat = mSkySettings->getMoonRotation();
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
}
//-------------------------------------------------------------------------
@ -583,10 +607,47 @@ void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged()
void LLPanelSettingsSkySunMoonTab::onSunRotationChanged()
{
if (!mSkySettings) return;
mSkySettings->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation());
mSkySettings->update();
setIsDirty();
LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
F32 azimuth, elevation;
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
if (mSkySettings)
{
mSkySettings->setSunRotation(quat);
mSkySettings->update();
setIsDirty();
}
}
void LLPanelSettingsSkySunMoonTab::onSunAzimElevChanged()
{
F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
LLQuaternion quat;
azimuth *= DEG_TO_RAD;
elevation *= DEG_TO_RAD;
if (is_approx_zero(elevation))
{
elevation = F_APPROXIMATELY_ZERO;
}
quat.setAngleAxis(-elevation, 0, 1, 0);
LLQuaternion az_quat;
az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
quat *= az_quat;
getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
if (mSkySettings)
{
mSkySettings->setSunRotation(quat);
mSkySettings->update();
setIsDirty();
}
}
void LLPanelSettingsSkySunMoonTab::onSunScaleChanged()
@ -607,10 +668,48 @@ void LLPanelSettingsSkySunMoonTab::onSunImageChanged()
void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged()
{
if (!mSkySettings) return;
mSkySettings->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation());
mSkySettings->update();
setIsDirty();
LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
F32 azimuth, elevation;
LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
if (mSkySettings)
{
mSkySettings->setMoonRotation(quat);
mSkySettings->update();
setIsDirty();
}
}
void LLPanelSettingsSkySunMoonTab::onMoonAzimElevChanged()
{
F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
LLQuaternion quat;
azimuth *= DEG_TO_RAD;
elevation *= DEG_TO_RAD;
if (is_approx_zero(elevation))
{
elevation = F_APPROXIMATELY_ZERO;
}
quat.setAngleAxis(-elevation, 0, 1, 0);
LLQuaternion az_quat;
az_quat.setAngleAxis(F_TWO_PI- azimuth, 0, 0, 1);
quat *= az_quat;
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
if (mSkySettings)
{
mSkySettings->setMoonRotation(quat);
mSkySettings->update();
setIsDirty();
}
}
void LLPanelSettingsSkySunMoonTab::onMoonImageChanged()

View File

@ -124,9 +124,11 @@ private:
void onGlowChanged();
void onStarBrightnessChanged();
void onSunRotationChanged();
void onSunAzimElevChanged();
void onSunScaleChanged();
void onSunImageChanged();
void onMoonRotationChanged();
void onMoonAzimElevChanged();
void onMoonScaleChanged();
void onMoonBrightnessChanged();
void onMoonImageChanged();

View File

@ -52,7 +52,6 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
@ -106,6 +105,18 @@ void LLPanelLandmarkInfo::resetLocation()
// virtual
void LLPanelLandmarkInfo::setInfoType(EInfoType type)
{
LLUUID dest_folder;
setInfoType(type, dest_folder);
}
// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id)
{
setInfoType(CREATE_LANDMARK, fodler_id);
}
void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id)
{
LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
@ -183,7 +194,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
// remote parcel request to complete.
if (!LLLandmarkActions::landmarkAlreadyExists())
{
createLandmark(LLUUID());
createLandmark(folder_id);
}
}
break;
@ -504,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
return left.second < right.second;
}
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
{
LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
@ -517,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
items,
LLInventoryModel::EXCLUDE_TRASH,
is_category);
// Add the "My Favorites" category.
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
if (!favorites_cat)
{
LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
}
else
{
cats.push_back(favorites_cat);
}
}
/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
mItem->setParent(mNewParentId);
mItem->updateParentOnServer(FALSE);
gInventory.updateItem(mItem);
gInventory.notifyObservers();
}

View File

@ -28,6 +28,7 @@
#define LL_LLPANELLANDMARKINFO_H
#include "llpanelplaceinfo.h"
#include "llinventorymodel.h"
class LLComboBox;
class LLLineEditor;
@ -43,8 +44,12 @@ public:
/*virtual*/ void resetLocation();
// If landmark doesn't exists, will create it at default folder
/*virtual*/ void setInfoType(EInfoType type);
// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
void setInfoAndCreateLandmark(const LLUUID& fodler_id);
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
// Displays landmark owner, creator and creation date info.
@ -59,13 +64,19 @@ public:
// Select current landmark folder in combobox.
BOOL setLandmarkFolder(const LLUUID& id);
// Create a landmark for the current location
// in a folder specified by folder_id.
void createLandmark(const LLUUID& folder_id);
typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
private:
// Create a landmark for the current location
// in a folder specified by folder_id.
// Expects title and description to be initialized
void createLandmark(const LLUUID& folder_id);
// If landmark doesn't exists, will create it at specified folder
void setInfoType(EInfoType type, const LLUUID &folder_id);
void populateFoldersList();
LLTextBox* mOwner;
@ -77,4 +88,17 @@ private:
LLComboBox* mFolderCombo;
};
class LLUpdateLandmarkParent : public LLInventoryCallback
{
public:
LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
mItem(item),
mNewParentId(new_parent)
{};
/* virtual */ void fire(const LLUUID& inv_item_id);
private:
LLPointer<LLViewerInventoryItem> mItem;
LLUUID mNewParentId;
};
#endif // LL_LLPANELLANDMARKINFO_H

File diff suppressed because it is too large Load Diff

View File

@ -50,81 +50,69 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
{
public:
LLLandmarksPanel();
LLLandmarksPanel(bool is_landmark_panel);
virtual ~LLLandmarksPanel();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onSearchEdit(const std::string& string);
/*virtual*/ void onShowOnMap();
/*virtual*/ void onShowProfile();
/*virtual*/ void onTeleport();
/*virtual*/ void updateVerbs();
/*virtual*/ bool isSingleItemSelected();
BOOL postBuild() override;
void onSearchEdit(const std::string& string) override;
void onShowOnMap() override;
void onShowProfile() override;
void onTeleport() override;
void onRemoveSelected() override;
void updateVerbs() override;
bool isSingleItemSelected() override;
LLToggleableMenu* getSelectionMenu() override;
LLToggleableMenu* getSortingMenu() override;
LLToggleableMenu* getCreateMenu() override;
/**
* Processes drag-n-drop of the Landmarks and folders into trash button.
*/
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override;
void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onSelectorButtonClicked();
void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list)
{
mCurrentSelectedList = inventory_list;
}
/**
* Update filter ShowFolderState setting to show empty folder message
* if Landmarks inventory folder is empty.
*/
void updateShowFolderState();
/**
* Selects item with "obj_id" in one of accordion tabs.
*/
void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; }
void updateMenuVisibility(LLUICtrl* menu);
void doCreatePick(LLLandmark* landmark, const LLUUID &item_id );
void resetSelection();
protected:
/**
* @return true - if current selected panel is not null and selected item is a landmark
*/
bool isLandmarkSelected() const;
bool isFolderSelected() const;
bool isReceivedFolderSelected() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
/**
* Selects item with "obj_id" in "inventory_list" and scrolls accordion
* scrollbar to show the item.
* Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
*/
LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
const std::string& tab_name,
const LLUUID& obj_id,
BOOL take_keyboard_focus) const;
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
//LLRemoteParcelInfoObserver interface
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
/*virtual*/ void setParcelID(const LLUUID& parcel_id);
/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
private:
void initFavoritesInventoryPanel();
void initLandmarksInventoryPanel();
void initMyInventoryPanel();
void initLibraryInventoryPanel();
void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);
void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);
void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list);
void processParcelInfo(const LLParcelData& parcel_data) override;
void setParcelID(const LLUUID& parcel_id) override;
void setErrorStatus(S32 status, const std::string& reason) override;
// List Commands Handlers
void initListCommandsHandlers();
void updateListCommands();
void onActionsButtonClick();
void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
LLPlacesInventoryPanel* mCurrentSelectedList;
private:
void initLandmarksInventoryPanel();
void onTrashButtonClick() const;
void onAddAction(const LLSD& command_name) const;
void onClipboardAction(const LLSD& command_name) const;
@ -150,39 +138,34 @@ private:
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Processes drag-n-drop of the Landmarks and folders into trash button.
*/
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
*/
void doShowOnMap(LLLandmark* landmark);
void doProcessParcelInfo(LLLandmark* landmark,
LLFolderViewItem* cur_item,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data);
void doCreatePick(LLLandmark* landmark);
private:
LLPlacesInventoryPanel* mFavoritesInventoryPanel;
LLPlacesInventoryPanel* mLandmarksInventoryPanel;
LLPlacesInventoryPanel* mMyInventoryPanel;
LLPlacesInventoryPanel* mLibraryInventoryPanel;
LLMenuButton* mGearButton;
LLToggleableMenu* mGearLandmarkMenu;
LLToggleableMenu* mGearFolderMenu;
LLMenuGL* mMenuAdd;
LLPlacesInventoryPanel* mCurrentSelectedList;
LLInventoryObserver* mInventoryObserver;
LLToggleableMenu* mSortingMenu;
LLToggleableMenu* mAddMenu;
LLPanel* mListCommands;
bool isLandmarksPanel;
typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
accordion_tabs_t mAccordionTabs;
LLUUID mCreatePickItemId; // item we requested a pick for
};
LLAccordionCtrlTab* mMyLandmarksAccordionTab;
class LLFavoritesPanel : public LLLandmarksPanel
{
public:
LLFavoritesPanel();
BOOL postBuild() override;
void initFavoritesInventoryPanel();
};
#endif //LL_LLPANELLANDMARKS_H

View File

@ -129,6 +129,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mSavedFolderState(NULL),
mFilterText(""),
mMenuGearDefault(NULL),
mMenuVisibility(NULL),
mMenuAddHandle(),
mNeedUploadCost(true),
mSearchTypeCombo(NULL) // <FS:Ansariel> Properly initialize this
@ -320,6 +321,18 @@ BOOL LLPanelMainInventory::postBuild()
// </FS:Ansariel>
}
}
if(mActivePanel)
{
if(savedFilterState.has(mActivePanel->getFilter().getName()))
{
LLSD items = savedFilterState.get(mActivePanel->getFilter().getName());
LLInventoryFilter::Params p;
LLParamSDParser parser;
parser.readSD(items, p);
mActivePanel->getFilter().setSearchVisibilityTypes(p);
}
}
}
mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
@ -334,6 +347,7 @@ BOOL LLPanelMainInventory::postBuild()
// </FS:Zi> Filter dropdown
mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
initListCommandsHandlers();
const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
@ -358,6 +372,9 @@ BOOL LLPanelMainInventory::postBuild()
LLPanelMainInventory::~LLPanelMainInventory( void )
{
// Save the filters state.
// Some params types cannot be saved this way
// for example, LLParamSDParser doesn't know about U64,
// so some FilterOps params should be revised.
LLSD filterRoot;
LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
if (all_items_panel)
@ -1611,6 +1628,10 @@ void LLPanelMainInventory::initListCommandsHandlers()
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAddHandle = menu->getHandle();
mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mVisibilityMenuButton->setMenu(mMenuVisibility);
mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT);
// Update the trash button when selected item(s) get worn or taken off.
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
}
@ -1808,6 +1829,21 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
LLFloaterReg::showInstance("linkreplace", params);
}
if (command_name == "toggle_search_trash")
{
mActivePanel->getFilter().toggleSearchVisibilityTrash();
}
if (command_name == "toggle_search_library")
{
mActivePanel->getFilter().toggleSearchVisibilityLibrary();
}
if (command_name == "include_links")
{
mActivePanel->getFilter().toggleSearchVisibilityLinks();
}
}
void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
@ -1962,6 +1998,21 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
}
if (command_name == "toggle_search_trash")
{
return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0;
}
if (command_name == "toggle_search_library")
{
return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0;
}
if (command_name == "include_links")
{
return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;
}
if (command_name == "add_objects_on_double_click")
{
return gSavedSettings.getBOOL("FSDoubleClickAddInventoryObjects");

View File

@ -86,7 +86,6 @@ public:
void selectAllItemsPanel();
// <FS:Ansariel> FIRE-19493: "Show Original" should open main inventory panel
void showAllItemsPanel();
void resetFilters();
// </FS:Ansariel>
const std::string& getFilterText() const { return mFilterText; }
@ -101,6 +100,8 @@ public:
void toggleFindOptions();
void resetFilters();
// <FS:Zi> Filter dropdown
void onFilterTypeSelected(const std::string& filter_type_name);
void updateFilterDropdown(const LLInventoryFilter* filter);
@ -135,8 +136,6 @@ protected:
void doToSelected(const LLSD& userdata);
void closeAllFolders();
void doCreate(const LLSD& userdata);
// <FS:Ansariel> FIRE-19493: "Show Original" should open main inventory panel
//void resetFilters(); // Moved to public
// <FS:Zi> Sort By menu handlers
void setSortBy(const LLSD& userdata);
@ -218,7 +217,9 @@ protected:
private:
LLDragAndDropButton* mTrashButton;
LLToggleableMenu* mMenuGearDefault;
LLToggleableMenu* mMenuVisibility;
LLMenuButton* mGearMenuButton;
LLMenuButton* mVisibilityMenuButton;
LLHandle<LLView> mMenuAddHandle;
// <FS:Zi> Inventory Collapse and Expand Buttons

View File

@ -1439,6 +1439,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&do_nothing));
mCommitCallbackRegistrar.add("Inventory.SetFavoritesFolder", boost::bind(&do_nothing)); // <FS:Ansariel> Prevent warning "No callback found for: 'Inventory.SetFavoritesFolder' in control: Set Favorites folder"
mCommitCallbackRegistrar.add("Inventory.ResetFavoritesFolder", boost::bind(&do_nothing)); // <FS:Ansariel> Prevent warning "No callback found for: 'Inventory.ResetFavoritesFolder' in control: Reset Favorites folder"
mCommitCallbackRegistrar.add("Inventory.CustomAction", boost::bind(&do_nothing)); // <FS:Ansariel> Prevent warning "No callback found for: 'Inventory.CustomAction' in control: Find Links"
}

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