Merge viewer-release 6.3.2

master
Graham Linden 2019-09-10 12:07:01 -07:00
commit 3609eabe54
144 changed files with 2760 additions and 4878 deletions

View File

@ -552,3 +552,4 @@ ec09daf1899c1c01c4ba0ba950fae572f2a612a8 6.2.2-release
ab2ec5c5423b277d23fd0511ce50c15123ff2e03 6.2.3-release
67297f9902857e357570c44722ad84de3aff974e 6.2.4-release
9777aec6dc4a30a24537297ac040861ce16b82ae 6.3.0-release
ece699718f163921717bb95a6131e94af4c4138f 6.3.1-release

View File

@ -1083,6 +1083,7 @@ Nicky Dasmijn
MAINT-6665
SL-10291
SL-10293
SL-11061
SL-11072
Nicky Perian
OPEN-1

View File

@ -3,8 +3,8 @@
# cmake_minimum_required should appear before any
# other commands to guarantee full compatibility
# with the version specified
## prior to 3.4, the Windows manifest handling was missing
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
@ -83,6 +83,12 @@ add_dependencies(viewer secondlife-bin)
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
# sets the 'startup project' for debugging from visual studio.
set_property(
DIRECTORY ${VIEWER_PREFIX}
PROPERTY VS_STARTUP_PROJECT secondlife-bin
)
if (LL_TESTS)
# Define after the custom targets are created so
# individual apps can add themselves as dependencies

View File

@ -151,6 +151,8 @@ endif (LINUX)
if (DARWIN)
# Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default
set(CLANG_DISABLE_FATAL_WARNINGS OFF)
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations")

View File

@ -40,7 +40,7 @@ const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size
const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long
const S32 LLVORBISENC_CHUNK_SIZE_ERR = 11; // chunk size is wrong
const F32 LLVORBIS_CLIP_MAX_TIME = 10.0f;
const F32 LLVORBIS_CLIP_MAX_TIME = 30.0f;
const U8 LLVORBIS_CLIP_MAX_CHANNELS = 2;
const U32 LLVORBIS_CLIP_SAMPLE_RATE = 44100;
const U32 LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL = (U32)(LLVORBIS_CLIP_MAX_TIME * LLVORBIS_CLIP_SAMPLE_RATE);

View File

@ -1735,7 +1735,8 @@ bool LLStringUtilBase<T>::startsWith(
const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
if(0 == string.find(substr)) return true;
if (substr.length() > string.length()) return false;
if (0 == string.compare(0, substr.length(), substr)) return true;
return false;
}
@ -1746,9 +1747,11 @@ bool LLStringUtilBase<T>::endsWith(
const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
std::string::size_type idx = string.rfind(substr);
if(std::string::npos == idx) return false;
return (idx == (string.size() - substr.size()));
size_t sub_len = substr.length();
size_t str_len = string.length();
if (sub_len > str_len) return false;
if (0 == string.compare(str_len - sub_len, sub_len, substr)) return true;
return false;
}
// static

View File

@ -173,6 +173,19 @@ namespace
"-._~";
return s;
}
const std::string path()
{
static const std::string s =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"$-_.+"
"!*'(),"
"{}|\\^~[]`"
"<>#%"
";/?:@&=";
return s;
}
const std::string sub_delims()
{
static const std::string s = "!$&'()*+,;=";
@ -187,6 +200,12 @@ namespace
{ return LLURI::escape(s, unreserved() + ":@!$'()*+,"); } // sub_delims - "&;=" + ":@"
std::string escapeQueryValue(const std::string& s)
{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@"
std::string escapeUriQuery(const std::string& s)
{ return LLURI::escape(s, unreserved() + ":@?&$;*+=%/"); }
std::string escapeUriData(const std::string& s)
{ return LLURI::escape(s, unreserved() + "%"); }
std::string escapeUriPath(const std::string& s)
{ return LLURI::escape(s, path()); }
}
//static
@ -202,6 +221,85 @@ std::string LLURI::escape(const std::string& str)
return escape(str, default_allowed, true);
}
//static
std::string LLURI::escapePathAndData(const std::string &str)
{
std::string result;
const std::string data_marker = "data:";
if (str.compare(0, data_marker.length(), data_marker) == 0)
{
// This is not url, but data, data part needs to be properly escaped
// data part is separated by ',' from header. Minimal data uri is "data:,"
// See "data URI scheme"
size_t separator = str.find(',');
if (separator != std::string::npos)
{
size_t header_size = separator + 1;
std::string header = str.substr(0, header_size);
// base64 is url-safe
if (header.find("base64") != std::string::npos)
{
// assume url-safe data
result = str;
}
else
{
std::string data = str.substr(header_size, str.length() - header_size);
// Notes: File can be partially pre-escaped, that's why escaping ignores '%'
// It somewhat limits user from displaying strings like "%20" in text
// but that's how viewer worked for a while and user can double-escape it
// Header doesn't need escaping
result = header + escapeUriData(data);
}
}
}
else
{
// try processing it as path with query separator
// The query component is indicated by the first question
// mark("?") character and terminated by a number sign("#")
size_t delim_pos = str.find('?');
if (delim_pos == std::string::npos)
{
// alternate separator
delim_pos = str.find(';');
}
if (delim_pos != std::string::npos)
{
size_t path_size = delim_pos + 1;
std::string query;
std::string fragment;
size_t fragment_pos = str.find('#');
if (fragment_pos != std::string::npos)
{
query = str.substr(path_size, fragment_pos - path_size);
fragment = str.substr(fragment_pos);
}
else
{
query = str.substr(path_size);
}
std::string path = str.substr(0, path_size);
result = escapeUriPath(path) + escapeUriQuery(query) + escapeUriPath(fragment);
}
}
if (result.empty())
{
// Not a known scheme or no data part, try just escaping as Uri path
result = escapeUriPath(str);
}
return result;
}
LLURI::LLURI()
{
}

View File

@ -157,6 +157,14 @@ public:
const std::string& allowed,
bool is_allowed_sorted = false);
/**
* @brief Break string into data part and path or sheme
* and escape path (if present) and data.
* Data part is not allowed to have path related symbols
* @param str The raw URI to escape.
*/
static std::string escapePathAndData(const std::string &str);
/**
* @brief unescape an escaped URI string.
*

View File

@ -383,6 +383,41 @@ namespace tut
ensure_equals("query", u.query(), "redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
}
template<> template<>
void URITestObject::test<20>()
{
set_test_name("escapePathAndData uri test");
// Basics scheme:[//authority]path[?query][#fragment]
ensure_equals(LLURI::escapePathAndData("dirname?query"),
"dirname?query");
ensure_equals(LLURI::escapePathAndData("dirname?query=data"),
"dirname?query=data");
ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query#fragment"),
"host://dirname/subdir%20name?query#fragment");
ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query=some@>data#fragment"),
"host://dirname/subdir%20name?query=some@%3Edata#fragment");
ensure_equals(LLURI::escapePathAndData("host://dir[name/subdir name?query=some[data#fra[gment"),
"host://dir[name/subdir%20name?query=some%5Bdata#fra[gment");
ensure_equals(LLURI::escapePathAndData("mailto:zero@ll.com"),
"mailto:zero@ll.com");
// pre-escaped
ensure_equals(LLURI::escapePathAndData("host://dirname/subdir%20name"),
"host://dirname/subdir%20name");
// data:[<mediatype>][;base64],<data>
ensure_equals(LLURI::escapePathAndData("data:,Hello, World!"),
"data:,Hello%2C%20World%21");
ensure_equals(LLURI::escapePathAndData("data:text/html,<h1>Hello, World!</h1>"),
"data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
// pre-escaped
ensure_equals(LLURI::escapePathAndData("data:text/html,%3Ch1%3EHello%2C%20World!</h1>"),
"data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
// assume that base64 does not need escaping
ensure_equals(LLURI::escapePathAndData("data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="),
"data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?=");
}
}

View File

@ -355,7 +355,8 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
}
if (op->mStatus)
{
int http_status(HTTP_OK);
// note: CURLINFO_RESPONSE_CODE requires a long - https://curl.haxx.se/libcurl/c/CURLINFO_RESPONSE_CODE.html
long http_status(HTTP_OK);
if (handle)
{

View File

@ -181,7 +181,7 @@ bool LLImageBMP::updateData()
}
}
else
if( 12 <= header.mSize && 64 <= header.mSize )
if( 12 <= header.mSize && header.mSize <= 64 )
{
setLastError("OS/2 2.x BMP files are not supported");
return false;

View File

@ -401,7 +401,7 @@ public:
child->insert(data);
}
}
else
else if (parent)
{
//it's not in here, give it to the root
OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@ -416,6 +416,13 @@ public:
node->insert(data);
}
else
{
// It's not in here, and we are root.
// LLOctreeRoot::insert() should have expanded
// root by now, something is wrong
OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL;
}
return false;
}
@ -763,10 +770,15 @@ public:
{
LLOctreeNode<T>::insert(data);
}
else
else if (node->isInside(data->getPositionGroup()))
{
node->insert(data);
}
else
{
// calling node->insert(data) will return us to root
OCT_ERRS << "Failed to insert data at child node" << LL_ENDL;
}
}
else if (this->getChildCount() == 0)
{

View File

@ -265,7 +265,7 @@ LLSocket::~LLSocket()
void LLSocket::setBlocking(S32 timeout)
{
// set up the socket options
ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout));
ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE));

View File

@ -473,7 +473,8 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv)
{
LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
char buf[MAX_STRING];
LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len != outlen)
@ -483,13 +484,16 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = -1;
}
ms_sleep(1);
if (APR_SUCCESS == rv)
{
expected_len = maxinlen;
rv = apr_socket_recv(apr_socket, datain, &maxinlen);
if (rv != APR_SUCCESS)
{
LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
char buf[MAX_STRING];
LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len < maxinlen)

View File

@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) {
}
#endif
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
{
// Don't leak face objects. This is also needed to deal with
// changed font file names.
@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
}
int error;
#ifdef LL_WINDOWS
pFileStream = new llifstream(filename, std::ios::binary);
if (pFileStream->is_open())
{
std::streampos beg = pFileStream->tellg();
pFileStream->seekg(0, std::ios::end);
std::streampos end = pFileStream->tellg();
std::size_t file_size = end - beg;
pFileStream->seekg(0, std::ios::beg);
pFtStream = new LLFT_Stream();
pFtStream->base = 0;
pFtStream->pos = 0;
pFtStream->size = file_size;
pFtStream->descriptor.pointer = pFileStream;
pFtStream->read = ft_read_cb;
pFtStream->close = ft_close_cb;
FT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = (FT_StreamRec*)pFtStream;
error = FT_Open_Face(gFTLibrary,
&args,
0,
&mFTFace);
}
else
{
delete pFileStream;
pFileStream = NULL;
return FALSE;
}
error = ftOpenFace(filename, face_n);
#else
error = FT_New_Face( gFTLibrary,
filename.c_str(),
@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
if (error)
{
#ifdef LL_WINDOWS
pFileStream->close();
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
clearFontStreams();
#endif
return FALSE;
}
@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
// Clean up freetype libs.
FT_Done_Face(mFTFace);
#ifdef LL_WINDOWS
pFileStream->close();
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
clearFontStreams();
#endif
mFTFace = NULL;
return FALSE;
@ -285,18 +245,88 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
{
mStyle |= LLFontGL::BOLD;
mStyle &= ~LLFontGL::NORMAL;
}
if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
{
mStyle |= LLFontGL::ITALIC;
mStyle &= ~LLFontGL::NORMAL;
}
return TRUE;
}
S32 LLFontFreetype::getNumFaces(const std::string& filename)
{
if (mFTFace)
{
FT_Done_Face(mFTFace);
mFTFace = NULL;
}
S32 num_faces = 1;
#ifdef LL_WINDOWS
int error = ftOpenFace(filename, 0);
if (error)
{
return 0;
}
else
{
num_faces = mFTFace->num_faces;
}
FT_Done_Face(mFTFace);
clearFontStreams();
mFTFace = NULL;
#endif
return num_faces;
}
#ifdef LL_WINDOWS
S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
{
S32 error = -1;
pFileStream = new llifstream(filename, std::ios::binary);
if (pFileStream->is_open())
{
std::streampos beg = pFileStream->tellg();
pFileStream->seekg(0, std::ios::end);
std::streampos end = pFileStream->tellg();
std::size_t file_size = end - beg;
pFileStream->seekg(0, std::ios::beg);
pFtStream = new LLFT_Stream();
pFtStream->base = 0;
pFtStream->pos = 0;
pFtStream->size = file_size;
pFtStream->descriptor.pointer = pFileStream;
pFtStream->read = ft_read_cb;
pFtStream->close = ft_close_cb;
FT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = (FT_StreamRec*)pFtStream;
error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
}
return error;
}
void LLFontFreetype::clearFontStreams()
{
if (pFileStream)
{
pFileStream->close();
}
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
}
#endif
void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
{
mFallbackFonts = font;

View File

@ -84,7 +84,14 @@ public:
// is_fallback should be true for fallback fonts that aren't used
// to render directly (Unicode backup, primarily)
BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0);
S32 getNumFaces(const std::string& filename);
#ifdef LL_WINDOWS
S32 ftOpenFace(const std::string& filename, S32 face_n);
void clearFontStreams();
#endif
typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;

View File

@ -89,14 +89,24 @@ void LLFontGL::destroyGL()
mFontFreetype->destroyGL();
}
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
{
if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
mFontFreetype = new LLFontFreetype;
}
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n);
}
S32 LLFontGL::getNumFaces(const std::string& filename)
{
if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
mFontFreetype = new LLFontFreetype;
}
return mFontFreetype->getNumFaces(filename);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
@ -860,10 +870,6 @@ void LLFontGL::destroyAllGL()
U8 LLFontGL::getStyleFromString(const std::string &style)
{
S32 ret = 0;
if (style.find("NORMAL") != style.npos)
{
ret |= NORMAL;
}
if (style.find("BOLD") != style.npos)
{
ret |= BOLD;
@ -883,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style)
std::string LLFontGL::getStringFromStyle(U8 style)
{
std::string style_string;
if (style & NORMAL)
if (style == NORMAL)
{
style_string += "|NORMAL";
}

View File

@ -87,7 +87,9 @@ public:
void destroyGL();
BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0);
S32 getNumFaces(const std::string& filename);
S32 render(const LLWString &text, S32 begin_offset,
const LLRect& rect,

View File

@ -44,6 +44,8 @@ using std::map;
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
{
@ -60,6 +62,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,
{
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
const std::string& size,
const U8 style,
const string_vec_t& file_names,
const string_vec_t& ft_collection_listections) :
LLFontDescriptor(name, size, style, file_names)
{
mFontCollectionsList = ft_collection_listections;
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
const std::string& size,
const U8 style):
@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const
if (removeSubString(new_name,"Italic"))
new_style |= LLFontGL::ITALIC;
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());
}
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
success = success || init_succ;
}
}
//if (success)
// dump();
@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
std::string font_file_name = child->getTextContents();
desc.getFileNames().push_back(font_file_name);
if (child->hasAttribute("load_collection"))
{
BOOL col = FALSE;
child->getAttributeBOOL("load_collection", col);
if (col)
{
desc.getFontCollectionsList().push_back(font_file_name);
}
}
}
else if (child->hasName("os"))
{
@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
match_file_names.insert(match_file_names.begin(),
desc.getFileNames().begin(),
desc.getFileNames().end());
string_vec_t collections_list = match_desc->getFontCollectionsList();
collections_list.insert(collections_list.begin(),
desc.getFontCollectionsList().begin(),
desc.getFontCollectionsList().end());
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
new_desc.getFontCollectionsList() = collections_list;
registry->mFontMap.erase(*match_desc);
registry->mFontMap[new_desc] = NULL;
}
@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
// Build list of font names to look for.
// Files specified for this font come first, followed by those from the default descriptor.
string_vec_t file_names = match_desc->getFileNames();
string_vec_t ft_collection_list = match_desc->getFontCollectionsList();
string_vec_t default_file_names;
LLFontDescriptor default_desc("default",s_template_string,0);
const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
file_names.insert(file_names.end(),
match_default_desc->getFileNames().begin(),
match_default_desc->getFileNames().end());
ft_collection_list.insert(ft_collection_list.end(),
match_default_desc->getFontCollectionsList().begin(),
match_default_desc->getFontCollectionsList().end());
}
// Add ultimate fallback list - generated dynamically on linux,
@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
file_name_it != file_names.end();
++file_name_it)
{
LLFontGL *fontp = new LLFontGL;
std::string font_path = local_path + *file_name_it;
LLFontGL *fontp = NULL;
string_vec_t font_paths;
font_paths.push_back(local_path + *file_name_it);
font_paths.push_back(sys_path + *file_name_it);
#if LL_DARWIN
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
#endif
bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
// *HACK: Fallback fonts don't render, so we can use that to suppress
// creation of OpenGL textures for test apps. JC
BOOL is_fallback = !is_first_found || !mCreateGLTextures;
F32 extra_scale = (is_fallback)?fallback_scale:1.0;
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
F32 point_size_scale = extra_scale * point_size;
bool is_font_loaded = false;
for(string_vec_t::iterator font_paths_it = font_paths.begin();
font_paths_it != font_paths.end();
++font_paths_it)
{
font_path = sys_path + *file_name_it;
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
fontp = new LLFontGL;
S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1;
for (S32 i = 0; i < num_faces; i++)
{
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
delete fontp;
fontp = NULL;
if (fontp == NULL)
{
fontp = new LLFontGL;
}
if (fontp->loadFace(*font_paths_it, point_size_scale,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i))
{
is_font_loaded = true;
if (is_first_found)
{
result = fontp;
is_first_found = false;
}
else
{
fontlist.push_back(fontp->mFontFreetype);
delete fontp;
fontp = NULL;
}
}
else
{
delete fontp;
fontp = NULL;
}
}
if (is_font_loaded) break;
}
if(fontp)
if(!is_font_loaded)
{
if (is_first_found)
{
result = fontp;
is_first_found = false;
}
else
{
fontlist.push_back(fontp->mFontFreetype);
delete fontp;
fontp = NULL;
}
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
delete fontp;
fontp = NULL;
}
}

View File

@ -40,6 +40,7 @@ public:
LLFontDescriptor();
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names);
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections);
LLFontDescriptor normalize() const;
bool operator<(const LLFontDescriptor& b) const;
@ -52,6 +53,8 @@ public:
void setSize(const std::string& size) { mSize = size; }
const std::vector<std::string>& getFileNames() const { return mFileNames; }
std::vector<std::string>& getFileNames() { return mFileNames; }
const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; }
std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; }
const U8 getStyle() const { return mStyle; }
void setStyle(U8 style) { mStyle = style; }
@ -59,6 +62,7 @@ private:
std::string mName;
std::string mSize;
string_vec_t mFileNames;
string_vec_t mFontCollectionsList;
U8 mStyle;
};

View File

@ -122,6 +122,7 @@ void LLTextBox::setEnabled(BOOL enabled)
LLTextBase::setReadOnly(read_only);
updateSegments();
}
LLTextBase::setEnabled(enabled);
}
void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params )

View File

@ -44,7 +44,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
if (!success)
{
LL_ERRS() << "Couldn't load string table " << xml_filename << LL_ENDL;
LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
return false;
}

View File

@ -110,9 +110,9 @@ void glSwapBuffers(void* context);
CGLContextObj getCGLContextObj(GLViewRef view);
unsigned long getVramSize(GLViewRef view);
float getDeviceUnitSize(GLViewRef view);
const CGPoint getContentViewBoundsPosition(NSWindowRef window);
const CGSize getContentViewBoundsSize(NSWindowRef window);
const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
CGPoint getContentViewBoundsPosition(NSWindowRef window);
CGSize getContentViewBoundsSize(NSWindowRef window);
CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
void getWindowSize(NSWindowRef window, float* size);
void setWindowSize(NSWindowRef window, int width, int height);
void getCursorPos(NSWindowRef window, float* pos);

View File

@ -258,17 +258,17 @@ float getDeviceUnitSize(GLViewRef view)
return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
}
const CGPoint getContentViewBoundsPosition(NSWindowRef window)
CGPoint getContentViewBoundsPosition(NSWindowRef window)
{
return [[(LLNSWindow*)window contentView] bounds].origin;
}
const CGSize getContentViewBoundsSize(NSWindowRef window)
CGSize getContentViewBoundsSize(NSWindowRef window)
{
return [[(LLNSWindow*)window contentView] bounds].size;
}
const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
{
return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
}

View File

@ -382,7 +382,10 @@ void callWindowFocus()
void callWindowUnfocus()
{
gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
{
gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
}
}
void callWindowHide()

View File

@ -741,6 +741,17 @@ void LLWindowWin32::restore()
SetFocus(mWindowHandle);
}
bool destroy_window_handler(HWND &hWnd)
{
__try
{
return DestroyWindow(hWnd);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
}
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
@ -814,7 +825,7 @@ void LLWindowWin32::close()
ShowWindow(mWindowHandle, SW_HIDE);
// This causes WM_DESTROY to be sent *immediately*
if (!DestroyWindow(mWindowHandle))
if (!destroy_window_handler(mWindowHandle))
{
OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
mCallbacks->translateString("MBShutdownErr"),

View File

@ -531,7 +531,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
}
// now we can set page zoom factor
mCEFLib->setPageZoom(message_in.getValueReal("factor"));
F32 factor = (F32)message_in.getValueReal("factor");
#if LL_DARWIN
//temporary fix for SL-10473: issue with displaying checkboxes on Mojave
factor*=1.001;
#endif
mCEFLib->setPageZoom(factor);
// Plugin gets to decide the texture parameters to use.
mDepth = 4;
@ -736,6 +741,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
if (message_name == "set_page_zoom_factor")
{
F32 factor = (F32)message_in.getValueReal("factor");
#if LL_DARWIN
//temporary fix for SL-10473: issue with displaying checkboxes on Mojave
factor*=1.001;
#endif
mCEFLib->setPageZoom(factor);
}
if (message_name == "browse_stop")
@ -813,7 +822,8 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
// adding new code below in unicodeInput means we don't send ascii chars
// here too or we get double key presses on a mac.
bool esc_key = (event_umodchars == 27);
if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f ))
bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP);
if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up)
{
mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
event_keycode, event_chars,

View File

@ -200,7 +200,6 @@ set(viewer_SOURCE_FILES
llexperiencelog.cpp
llexternaleditor.cpp
llface.cpp
llfacebookconnect.cpp
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
@ -241,7 +240,6 @@ set(viewer_SOURCE_FILES
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
llfloaterfacebook.cpp
llfloaterfixedenvironment.cpp
llfloaterflickr.cpp
llfloaterfonttest.cpp
@ -827,7 +825,6 @@ set(viewer_HEADER_FILES
llexperiencelog.h
llexternaleditor.h
llface.h
llfacebookconnect.h
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
@ -868,7 +865,6 @@ set(viewer_HEADER_FILES
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
llfloaterfacebook.h
llfloaterfixedenvironment.h
llfloaterflickr.h
llfloaterfonttest.h
@ -1880,12 +1876,12 @@ if (WINDOWS)
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
if (NOT UNATTENDED)
set_property(
TARGET ${VIEWER_BINARY_NAME}
PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
endif (NOT UNATTENDED)
if (PACKAGE)
add_custom_command(

View File

@ -228,16 +228,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="snapshot"
/>
<command name="facebook"
available_in_toybox="true"
icon="Command_Facebook_Icon"
label_ref="Command_Facebook_Label"
tooltip_ref="Command_Facebook_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
execute_parameters="facebook"
is_running_function="Floater.IsOpen"
is_running_parameters="facebook"
/>
<command name="flickr"
available_in_toybox="true"
icon="Command_Flickr_Icon"

View File

@ -414,5 +414,16 @@
<key>Value</key>
<string>Snapshot</string>
</map>
<key>ExperienceSearchMaturity</key>
<map>
<key>Comment</key>
<string>Setting for the user's preferred Max Content rating for Experiences search (Default rating is General)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2</integer>
</map>
</map>
</llsd>

View File

@ -21,7 +21,6 @@
<command name="voice"/>
<command name="minimap"/>
<command name="snapshot"/>
<command name="facebook"/>
</left_toolbar>
<right_toolbar
button_display_mode="icons_only">

View File

@ -346,6 +346,11 @@ Call CheckWillUninstallV2 # Check if Second Life is already installed
StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
PRESERVE_DONE:
# Viewer had "SLLauncher" for some time and we was seting "IsHostApp" for viewer, make sure to clean it up
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
ClearErrors
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
@ -417,7 +422,7 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
# Write out uninstaller
@ -464,7 +469,7 @@ DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}"
DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
# BUG-2707 Remove entry that disabled SEHOP
DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
# Clean up shortcuts

View File

@ -743,7 +743,7 @@ BOOL LLAgent::getFlying() const
//-----------------------------------------------------------------------------
// setFlying()
//-----------------------------------------------------------------------------
void LLAgent::setFlying(BOOL fly)
void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
{
if (isAgentAvatarValid())
{
@ -772,7 +772,10 @@ void LLAgent::setFlying(BOOL fly)
// parcel doesn't let you start fly
// gods can always fly
// and it's OK if you're already flying
if (fail_sound)
{
make_ui_sound("UISndBadKeystroke");
}
return;
}
if( !was_flying )

View File

@ -204,7 +204,7 @@ public:
protected:
void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition
private:
mutable LLVector3d mPositionGlobal;
mutable LLVector3d mPositionGlobal;
position_signal_t mOnPositionChanged;
LLVector3d mLastTestGlobal;
@ -345,7 +345,7 @@ private:
//--------------------------------------------------------------------
public:
BOOL getFlying() const;
void setFlying(BOOL fly);
void setFlying(BOOL fly, BOOL fail_sound = FALSE);
static void toggleFlying();
static bool enableFlying();
BOOL canFly(); // Does this parcel allow you to fly?

View File

@ -1146,30 +1146,30 @@ bool LLAppViewer::init()
#if LL_RELEASE_FOR_DOWNLOAD
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
{
LLProcess::Params updater;
updater.desc = "updater process";
// Because it's the updater, it MUST persist beyond the lifespan of the
// viewer itself.
updater.autokill = false;
LLProcess::Params updater;
updater.desc = "updater process";
// Because it's the updater, it MUST persist beyond the lifespan of the
// viewer itself.
updater.autokill = false;
#if LL_WINDOWS
updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
#elif LL_DARWIN
// explicitly run the system Python interpreter on SLVersionChecker.py
updater.executable = "python";
updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
// explicitly run the system Python interpreter on SLVersionChecker.py
updater.executable = "python";
updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
#else
updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
#endif
// add LEAP mode command-line argument to whichever of these we selected
updater.args.add("leap");
// UpdaterServiceSettings
updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
// channel
updater.args.add(LLVersionInfo::getChannel());
// testok
updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
// add LEAP mode command-line argument to whichever of these we selected
updater.args.add("leap");
// UpdaterServiceSettings
updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
// channel
updater.args.add(LLVersionInfo::getChannel());
// testok
updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
// Run the updater. An exception from launching the updater should bother us.
LLLeap::create(updater, true);
@ -2443,9 +2443,9 @@ bool LLAppViewer::initConfiguration()
bool set_defaults = true;
if(!loadSettingsFromDirectory("Default", set_defaults))
{
std::ostringstream msg;
msg << "Unable to load default settings file. The installation may be corrupted.";
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
OSMessageBox(
"Unable to load default settings file. The installation may be corrupted.",
LLStringUtil::null,OSMB_OK);
return false;
}
@ -2566,7 +2566,7 @@ bool LLAppViewer::initConfiguration()
if(gSavedSettings.getBOOL("DisableCrashLogger"))
{
LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
LLAppViewer::instance()->disableCrashlogger();
disableCrashlogger();
}
// Handle initialization from settings.
@ -2583,7 +2583,7 @@ bool LLAppViewer::initConfiguration()
LL_INFOS() << msg.str() << LL_ENDL;
OSMessageBox(
msg.str().c_str(),
msg.str(),
LLStringUtil::null,
OSMB_OK);
@ -2693,7 +2693,34 @@ bool LLAppViewer::initConfiguration()
ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
// Examining "Language" may not suffice -- see LLUI::getLanguage()
// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
// good because we haven't yet called LLUI::initClass().
gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
gSavedSettings.getString("Language"));
}
if (gSavedSettings.getBOOL("SpellCheck"))
{
std::list<std::string> dict_list;
std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
if (!dict_list.empty())
{
LLSpellChecker::setUseSpellCheck(dict_list.front());
dict_list.pop_front();
LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
}
}
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
// This initial-SLURL logic, up through the call to
// sendURLToOtherInstance(), must precede LLSplashScreen::show() --
// because if sendURLToOtherInstance() succeeds, we take a fast exit,
// SKIPPING the splash screen and everything else.
// *FIX: This init code should be made more robust to prevent
// the issue SL-55321 from returning. One thought is to allow
@ -2738,6 +2765,27 @@ bool LLAppViewer::initConfiguration()
}
}
// NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
if ( !nextLoginLocation.empty() )
{
LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
}
else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
&& gSavedSettings.getString("CmdLineLoginLocation").empty())
{
// If automatic login from command line with --login switch
// init StartSLURL location.
std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
}
else
{
// the login location will be set by the login panel (see LLPanelLogin)
}
//RN: if we received a URL, hand it off to the existing instance.
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
@ -2753,30 +2801,6 @@ bool LLAppViewer::initConfiguration()
}
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
// Examining "Language" may not suffice -- see LLUI::getLanguage()
// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
// good because we haven't yet called LLUI::initClass().
gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
gSavedSettings.getString("Language"));
}
if (gSavedSettings.getBOOL("SpellCheck"))
{
std::list<std::string> dict_list;
std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
if (!dict_list.empty())
{
LLSpellChecker::setUseSpellCheck(dict_list.front());
dict_list.pop_front();
LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
}
}
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
std::string splash_msg;
@ -2808,30 +2832,15 @@ bool LLAppViewer::initConfiguration()
}
LLStringUtil::truncate(gWindowTitle, 255);
//RN: if we received a URL, hand it off to the existing instance.
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
// out of different directories
if (LLStartUp::getStartSLURL().isValid() &&
(gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
{
if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
{
// successfully handed off URL to existing instance, exit
return false;
}
}
//
// Check for another instance of the app running
// This happens AFTER LLSplashScreen::show(). That may or may not be
// important.
//
if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
{
std::ostringstream msg;
msg << LLTrans::getString("MBAlreadyRunning");
OSMessageBox(
msg.str(),
LLTrans::getString("MBAlreadyRunning"),
LLStringUtil::null,
OSMB_OK);
return false;
@ -2849,27 +2858,6 @@ bool LLAppViewer::initConfiguration()
}
}
// NextLoginLocation is set from the command line option
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
if ( !nextLoginLocation.empty() )
{
LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
}
else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
&& gSavedSettings.getString("CmdLineLoginLocation").empty())
{
// If automatic login from command line with --login switch
// init StartSLURL location.
std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
}
else
{
// the login location will be set by the login panel (see LLPanelLogin)
}
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
loadColorSettings();
@ -2893,7 +2881,14 @@ bool LLAppViewer::initConfiguration()
// keeps growing, necessitating a method all its own.
void LLAppViewer::initStrings()
{
LLTransUtil::parseStrings("strings.xml", default_trans_args);
std::string strings_file = "strings.xml";
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
{
// initial check to make sure files are there failed
LL_ERRS() << "Viewer failed to find localization and UI files. Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
}
LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");
// parseStrings() sets up the LLTrans substitution table. Add this one item.
@ -3178,6 +3173,10 @@ LLSD LLAppViewer::getViewerInfo() const
substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0);
info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution);
#if LL_DARWIN
info["HIDPI"] = gHiDPISupport;
#endif
// Libraries
info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
@ -3320,6 +3319,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const
}
support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
#if LL_DARWIN
support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string);
#endif
support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
if (info.has("COMPILER"))
{

View File

@ -374,12 +374,40 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
bool LLCommandLineParser::parseCommandLineString(const std::string& str)
{
std::string cmd_line_string("");
if (!str.empty())
{
bool add_last_c = true;
S32 last_c_pos = str.size() - 1; //don't get out of bounds on pos+1, last char will be processed separately
for (S32 pos = 0; pos < last_c_pos; ++pos)
{
cmd_line_string.append(&str[pos], 1);
if (str[pos] == '\\')
{
cmd_line_string.append("\\", 1);
if (str[pos + 1] == '\\')
{
++pos;
add_last_c = (pos != last_c_pos);
}
}
}
if (add_last_c)
{
cmd_line_string.append(&str[last_c_pos], 1);
if (str[last_c_pos] == '\\')
{
cmd_line_string.append("\\", 1);
}
}
}
// Split the string content into tokens
const char* escape_chars = "\\";
const char* separator_chars = "\r\n ";
const char* quote_chars = "\"'";
const char* escape_chars = "\\";
const char* separator_chars = "\r\n ";
const char* quote_chars = "\"'";
boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep);
boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
std::vector<std::string> tokens;
// std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();

View File

@ -564,24 +564,46 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
LLVector4a* normal,
LLVector4a* tangent)
{
if (!mRootVolp)
{
return NULL;
}
LLViewerObject* hit = NULL;
if (lineSegmentBoundingBox(start, end))
{
LLVector4a local_end = end;
LLVector4a local_intersection;
if (mRootVolp &&
mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
{
*intersection = local_intersection;
}
hit = mRootVolp;
}
else
{
std::vector<LLVOVolume*> volumes;
getAnimatedVolumes(volumes);
for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
{
LLVOVolume *volp = *vol_it;
if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
{
*intersection = local_intersection;
}
hit = volp;
break;
}
}
}
}
return hit;

View File

@ -1,714 +0,0 @@
/**
* @file llfacebookconnect.h
* @author Merov, Cho, Gil
* @brief Connection to Facebook Service
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, 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 "llfacebookconnect.h"
#include "llflickrconnect.h"
#include "lltwitterconnect.h"
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcommandhandler.h"
#include "llnotificationsutil.h"
#include "llurlaction.h"
#include "llimagepng.h"
#include "llimagejpeg.h"
#include "lltrans.h"
#include "llevents.h"
#include "llviewerregion.h"
#include "llviewercontrol.h"
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
#include "llcorehttputil.h"
boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent"));
// Local functions
void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
{
// Note: 302 (redirect) is *not* an error that warrants logging
if (status != 302)
{
LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
}
}
void toast_user_for_facebook_success()
{
LLSD args;
args["MESSAGE"] = LLTrans::getString("facebook_post_success");
LLNotificationsUtil::add("FacebookConnect", args);
}
LLCore::HttpHeaders::ptr_t get_headers()
{
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
// The DebugSlshareLogTag mechanism is intended to trigger slshare-service
// debug logging. slshare-service is coded to respond to an X-debug-tag
// header by engaging debug logging for that request only. This way a
// developer need not muck with the slshare-service image to engage debug
// logging. Moreover, the value of X-debug-tag is embedded in each such
// log line so the developer can quickly find the log lines pertinent to
// THIS session.
std::string logtag(gSavedSettings.getString("DebugSlshareLogTag"));
if (! logtag.empty())
{
httpHeaders->append("X-debug-tag", logtag);
}
return httpHeaders;
}
///////////////////////////////////////////////////////////////////////////////
//
class LLFacebookConnectHandler : public LLCommandHandler
{
public:
LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (tokens.size() >= 1)
{
if (tokens[0].asString() == "connect")
{
if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
{
// this command probably came from the flickr_web browser, so close it
LLFloaterReg::hideInstance("flickr_web");
// connect to flickr
if (query_map.has("oauth_token"))
{
LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
}
return true;
}
else if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
{
// this command probably came from the twitter_web browser, so close it
LLFloaterReg::hideInstance("twitter_web");
// connect to twitter
if (query_map.has("oauth_token"))
{
LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
}
return true;
}
else //if (tokens.size() >= 2 && tokens[1].asString() == "facebook")
{
// this command probably came from the fbc_web browser, so close it
LLFloaterReg::hideInstance("fbc_web");
// connect to facebook
if (query_map.has("code"))
{
LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
}
return true;
}
}
}
return false;
}
};
LLFacebookConnectHandler gFacebookConnectHandler;
///////////////////////////////////////////////////////////////////////////////
//
void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
LLSD putData;
if (!authCode.empty())
{
putData["code"] = authCode;
}
if (!authState.empty())
{
putData["state"] = authState;
}
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->putAndSuspend(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers());
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
if (status == LLCore::HttpStatus(HTTP_FOUND))
{
std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
if (location.empty())
{
LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
}
else
{
openFacebookWeb(location);
}
}
}
else
{
LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_CONNECTED);
}
}
///////////////////////////////////////////////////////////////////////////////
//
bool LLFacebookConnect::testShareStatus(LLSD &result)
{
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (status)
return true;
if (status == LLCore::HttpStatus(HTTP_FOUND))
{
std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
if (location.empty())
{
LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
}
else
{
openFacebookWeb(location);
}
}
if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
{
LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
connectToFacebook();
}
else
{
LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_POST_FAILED);
log_facebook_connect_error("Share", status.getStatus(), status.toString(),
result.get("error_code"), result.get("error_description"));
}
return false;
}
void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers());
if (testShareStatus(result))
{
toast_user_for_facebook_success();
LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_POSTED);
}
}
void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpHeaders::ptr_t httpHeaders(get_headers());
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
std::string imageFormat;
if (dynamic_cast<LLImagePNG*>(image.get()))
{
imageFormat = "png";
}
else if (dynamic_cast<LLImageJPEG*>(image.get()))
{
imageFormat = "jpg";
}
else
{
LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
return;
}
// All this code is mostly copied from LLWebProfile::post()
static const std::string boundary = "----------------------------0123abcdefab";
std::string contentType = "multipart/form-data; boundary=" + boundary;
httpHeaders->append("Content-Type", contentType.c_str());
LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
LLCore::BufferArrayStream body(raw.get());
// *NOTE: The order seems to matter.
body << "--" << boundary << "\r\n"
<< "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
<< caption << "\r\n";
body << "--" << boundary << "\r\n"
<< "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
<< "Content-Type: image/" << imageFormat << "\r\n\r\n";
// Insert the image data.
// *FIX: Treating this as a string will probably screw it up ...
U8* image_data = image->getData();
for (S32 i = 0; i < image->getDataSize(); ++i)
{
body << image_data[i];
}
body << "\r\n--" << boundary << "--\r\n";
setConnectionState(LLFacebookConnect::FB_POSTING);
LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders);
if (testShareStatus(result))
{
toast_user_for_facebook_success();
LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_POSTED);
}
}
///////////////////////////////////////////////////////////////////////////////
//
void LLFacebookConnect::facebookDisconnectCoro()
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers());
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status && (status != LLCore::HttpStatus(HTTP_FOUND)))
{
LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(),
result.get("error_code"), result.get("error_description"));
}
else
{
LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL;
clearInfo();
clearContent();
//Notify state change
setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
}
}
///////////////////////////////////////////////////////////////////////////////
//
void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers());
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) )
{
LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
if (autoConnect)
{
connectToFacebook();
}
else
{
setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
}
}
else
{
LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
log_facebook_connect_error("Connected", status.getStatus(), status.toString(),
result.get("error_code"), result.get("error_description"));
}
}
else
{
LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL;
setConnectionState(LLFacebookConnect::FB_CONNECTED);
}
}
///////////////////////////////////////////////////////////////////////////////
//
void LLFacebookConnect::facebookConnectInfoCoro()
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers());
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (status == LLCore::HttpStatus(HTTP_FOUND))
{
std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
if (location.empty())
{
LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
}
else
{
openFacebookWeb(location);
}
}
else if (!status)
{
LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL;
log_facebook_connect_error("Info", status.getStatus(), status.toString(),
result.get("error_code"), result.get("error_description"));
}
else
{
LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
storeInfo(result);
}
}
///////////////////////////////////////////////////////////////////////////////
//
void LLFacebookConnect::facebookConnectFriendsCoro()
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers());
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (status == LLCore::HttpStatus(HTTP_FOUND))
{
std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
if (location.empty())
{
LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
}
else
{
openFacebookWeb(location);
}
}
else if (!status)
{
LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL;
log_facebook_connect_error("Info", status.getStatus(), status.toString(),
result.get("error_code"), result.get("error_description"));
}
else
{
LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL;
result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
storeContent(content);
}
}
///////////////////////////////////////////////////////////////////////////////
//
LLFacebookConnect::LLFacebookConnect()
: mConnectionState(FB_NOT_CONNECTED),
mConnected(false),
mInfo(),
mContent(),
mRefreshInfo(false),
mRefreshContent(false),
mReadFromMaster(false)
{
}
void LLFacebookConnect::openFacebookWeb(std::string url)
{
LLFloaterWebContent::Params p;
p.url(url);
p.show_chrome(true);
p.allow_back_forward_navigation(false);
p.clean_browser(true);
LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
//So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event
//occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
//fbc_web floater contains the "webbrowser" panel. JIRA: ACME-744
gFocusMgr.setKeyboardFocus( floater );
//LLUrlAction::openURLExternal(url);
}
std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master)
{
std::string url("");
LLViewerRegion *regionp = gAgent.getRegion();
if (regionp)
{
//url = "http://pdp15.lindenlab.com/fbc/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
url = regionp->getCapability("FacebookConnect");
url += route;
if (include_read_from_master && mReadFromMaster)
{
url += "?read_from_master=true";
}
}
return url;
}
void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
{
setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro",
boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state));
}
void LLFacebookConnect::disconnectFromFacebook()
{
LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro",
boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this));
}
void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
{
setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro",
boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect));
}
void LLFacebookConnect::loadFacebookInfo()
{
if(mRefreshInfo)
{
LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro",
boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this));
}
}
void LLFacebookConnect::loadFacebookFriends()
{
if(mRefreshContent)
{
LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro",
boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this));
}
}
void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name,
const std::string& description, const std::string& image, const std::string& message)
{
setConnectionState(LLFacebookConnect::FB_POSTING);
LLSD body;
if (!location.empty())
{
body["location"] = location;
}
if (!name.empty())
{
body["name"] = name;
}
if (!description.empty())
{
body["description"] = description;
}
if (!image.empty())
{
body["image"] = image;
}
if (!message.empty())
{
body["message"] = message;
}
LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body));
}
void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
{
setConnectionState(LLFacebookConnect::FB_POSTING);
LLSD body;
body["image"] = image_url;
body["caption"] = caption;
LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body));
}
void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
{
setConnectionState(LLFacebookConnect::FB_POSTING);
LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro",
boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption));
}
void LLFacebookConnect::updateStatus(const std::string& message)
{
LLSD body;
body["message"] = message;
setConnectionState(LLFacebookConnect::FB_POSTING);
LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body));
}
void LLFacebookConnect::storeInfo(const LLSD& info)
{
mInfo = info;
mRefreshInfo = false;
sInfoWatcher->post(info);
}
const LLSD& LLFacebookConnect::getInfo() const
{
return mInfo;
}
void LLFacebookConnect::clearInfo()
{
mInfo = LLSD();
}
void LLFacebookConnect::storeContent(const LLSD& content)
{
mContent = content;
mRefreshContent = false;
sContentWatcher->post(content);
}
const LLSD& LLFacebookConnect::getContent() const
{
return mContent;
}
void LLFacebookConnect::clearContent()
{
mContent = LLSD();
}
void LLFacebookConnect::setDataDirty()
{
mRefreshInfo = true;
mRefreshContent = true;
}
void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state)
{
if(connection_state == FB_CONNECTED)
{
mReadFromMaster = true;
setConnected(true);
setDataDirty();
}
else if(connection_state == FB_NOT_CONNECTED)
{
setConnected(false);
}
else if(connection_state == FB_POSTED)
{
mReadFromMaster = false;
}
if (mConnectionState != connection_state)
{
// set the connection state before notifying watchers
mConnectionState = connection_state;
LLSD state_info;
state_info["enum"] = connection_state;
sStateWatcher->post(state_info);
}
}
void LLFacebookConnect::setConnected(bool connected)
{
mConnected = connected;
}

View File

@ -1,116 +0,0 @@
/**
* @file llfacebookconnect.h
* @author Merov, Cho, Gil
* @brief Connection to Facebook Service
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, 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_LLFACEBOOKCONNECT_H
#define LL_LLFACEBOOKCONNECT_H
#include "llsingleton.h"
#include "llimage.h"
#include "llcoros.h"
#include "lleventcoro.h"
class LLEventPump;
/**
* @class LLFacebookConnect
*
* Manages authentication to, and interaction with, a web service allowing the
* the viewer to get Facebook OpenGraph data.
*/
class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
{
LLSINGLETON(LLFacebookConnect);
~LLFacebookConnect() {};
LOG_CLASS(LLFacebookConnect);
public:
enum EConnectionState
{
FB_NOT_CONNECTED = 0,
FB_CONNECTION_IN_PROGRESS = 1,
FB_CONNECTED = 2,
FB_CONNECTION_FAILED = 3,
FB_POSTING = 4,
FB_POSTED = 5,
FB_POST_FAILED = 6,
FB_DISCONNECTING = 7,
FB_DISCONNECT_FAILED = 8
};
void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = ""); // Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use.
void disconnectFromFacebook(); // Disconnect from the FBC service.
void checkConnectionToFacebook(bool auto_connect = false); // Check if an access token is available on the FBC service. If not, call connectToFacebook().
void loadFacebookInfo();
void loadFacebookFriends();
void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
void sharePhoto(const std::string& image_url, const std::string& caption);
void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
void updateStatus(const std::string& message);
void storeInfo(const LLSD& info);
const LLSD& getInfo() const;
void clearInfo();
void storeContent(const LLSD& content);
const LLSD& getContent() const;
void clearContent();
void setDataDirty();
void setConnectionState(EConnectionState connection_state);
void setConnected(bool connected);
bool isConnected() { return mConnected; }
bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); }
EConnectionState getConnectionState() { return mConnectionState; }
void openFacebookWeb(std::string url);
private:
std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
EConnectionState mConnectionState;
BOOL mConnected;
LLSD mInfo;
LLSD mContent;
bool mRefreshInfo;
bool mRefreshContent;
bool mReadFromMaster;
static boost::scoped_ptr<LLEventPump> sStateWatcher;
static boost::scoped_ptr<LLEventPump> sInfoWatcher;
static boost::scoped_ptr<LLEventPump> sContentWatcher;
bool testShareStatus(LLSD &results);
void facebookConnectCoro(std::string authCode, std::string authState);
void facebookConnectedCheckCoro(bool autoConnect);
void facebookDisconnectCoro();
void facebookShareCoro(std::string route, LLSD share);
void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption);
void facebookConnectInfoCoro();
void facebookConnectFriendsCoro();
};
#endif // LL_LLFACEBOOKCONNECT_H

View File

@ -43,6 +43,7 @@
#include "llsdserialize.h"
#include "lltooltip.h"
#include "llbutton.h"
#include "llscrollbar.h"
#include "llappviewer.h"
#include "llviewertexturelist.h"
@ -128,6 +129,7 @@ void LLFastTimerView::setPauseState(bool pause_state)
BOOL LLFastTimerView::postBuild()
{
LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
mScrollBar = getChild<LLScrollbar>("scroll_vert");
pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
return TRUE;
@ -183,7 +185,7 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (x < mBarRect.mLeft)
if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* idp = getLegendID(y);
if (idp)
@ -284,7 +286,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
}
}
}
else if (x < mBarRect.mLeft)
else if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* timer_id = getLegendID(y);
if (timer_id)
@ -335,7 +337,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
else
{
// tooltips for timer legend
if (x < mBarRect.mLeft)
if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* idp = getLegendID(y);
if (idp)
@ -352,10 +354,18 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if (x < mBarRect.mLeft)
{
// Inside mScrollBar and list of timers
mScrollBar->handleScrollWheel(x,y,clicks);
}
else
{
setPauseState(true);
mScrollIndex = llclamp( mScrollIndex + clicks,
0,
llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
}
return TRUE;
}
@ -1197,6 +1207,7 @@ void LLFastTimerView::drawLegend()
{
LLLocalClipRect clip(mLegendRect);
S32 cur_line = 0;
S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect
ft_display_idx.clear();
std::map<BlockTimerStatHandle*, S32> display_line;
for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
@ -1204,10 +1215,24 @@ void LLFastTimerView::drawLegend()
++it)
{
BlockTimerStatHandle* idp = (*it);
// Needed to figure out offsets and parenting
display_line[idp] = cur_line;
ft_display_idx.push_back(idp);
cur_line++;
if (scroll_offset < mScrollBar->getDocPos())
{
// only offset for visible items
scroll_offset += TEXT_HEIGHT + 2;
if (idp->getTreeNode().mCollapsed)
{
it.skipDescendants();
}
continue;
}
// used for mouse clicks
ft_display_idx.push_back(idp);
// Actual draw, first bar (square), then text
x = MARGIN;
LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT);
@ -1281,11 +1306,14 @@ void LLFastTimerView::drawLegend()
y -= (TEXT_HEIGHT + 2);
scroll_offset += TEXT_HEIGHT + 2;
if (idp->getTreeNode().mCollapsed)
{
it.skipDescendants();
}
}
// Recalculate scroll size
mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight());
}
}

View File

@ -33,6 +33,8 @@
#include "lltracerecording.h"
#include <deque>
class LLScrollbar;
class LLFastTimerView : public LLFloater
{
public:
@ -142,6 +144,8 @@ private:
mLegendRect;
LLFrameTimer mHighlightTimer;
LLTrace::PeriodicRecording mRecording;
LLScrollbar* mScrollBar;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +0,0 @@
/**
* @file llfloaterfacebook.h
* @brief Header file for llfloaterfacebook
* @author Gilbert@lindenlab.com
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, 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_LLFLOATERFACEBOOK_H
#define LL_LLFLOATERFACEBOOK_H
#include "llcallingcard.h"
#include "llfloater.h"
#include "lltextbox.h"
#include "llviewertexture.h"
class LLIconCtrl;
class LLCheckBoxCtrl;
class LLSnapshotLivePreview;
class LLAvatarList;
class LLFloaterBigPreview;
class LLFacebookStatusPanel : public LLPanel
{
public:
LLFacebookStatusPanel();
BOOL postBuild();
void draw();
void onSend();
bool onFacebookConnectStateChange(const LLSD& data);
bool onFacebookConnectAccountStateChange(const LLSD& data);
void sendStatus();
void clearAndClose();
private:
void onVisibilityChange(BOOL new_visibility);
bool onFacebookConnectInfoChange();
void onConnect();
void onUseAnotherAccount();
void onDisconnect();
void showConnectButton();
void hideConnectButton();
void showDisconnectedLayout();
void showConnectedLayout();
LLTextBox * mAccountCaptionLabel;
LLTextBox * mAccountNameLabel;
LLUICtrl * mPanelButtons;
LLUICtrl * mConnectButton;
LLUICtrl * mDisconnectButton;
LLUICtrl* mMessageTextEditor;
LLUICtrl* mPostButton;
LLUICtrl* mCancelButton;
};
class LLFacebookPhotoPanel : public LLPanel
{
public:
LLFacebookPhotoPanel();
~LLFacebookPhotoPanel();
BOOL postBuild();
void draw();
LLSnapshotLivePreview* getPreviewView();
void onVisibilityChange(BOOL new_visibility);
void onClickBigPreview();
void onClickNewSnapshot();
void onSend();
S32 notify(const LLSD& info);
bool onFacebookConnectStateChange(const LLSD& data);
void sendPhoto();
void clearAndClose();
void updateControls();
void updateResolution(BOOL do_update);
void checkAspectRatio(S32 index);
LLUICtrl* getRefreshBtn();
private:
bool isPreviewVisible();
void attachPreview();
LLHandle<LLView> mPreviewHandle;
LLUICtrl * mResolutionComboBox;
LLUICtrl * mFilterComboBox;
LLUICtrl * mRefreshBtn;
LLUICtrl * mWorkingLabel;
LLUICtrl * mThumbnailPlaceholder;
LLUICtrl * mCaptionTextBox;
LLUICtrl * mPostButton;
LLUICtrl * mCancelButton;
LLButton * mBtnPreview;
LLFloaterBigPreview * mBigPreviewFloater;
S32 mQuality; // Compression quality
};
class LLFacebookCheckinPanel : public LLPanel
{
public:
LLFacebookCheckinPanel();
BOOL postBuild();
void draw();
void onSend();
bool onFacebookConnectStateChange(const LLSD& data);
void sendCheckin();
void clearAndClose();
private:
std::string mMapUrl;
LLPointer<LLViewerFetchedTexture> mMapTexture;
LLUICtrl* mPostButton;
LLUICtrl* mCancelButton;
LLUICtrl* mMessageTextEditor;
LLUICtrl* mMapLoadingIndicator;
LLIconCtrl* mMapPlaceholder;
LLIconCtrl* mMapDefault;
LLCheckBoxCtrl* mMapCheckBox;
bool mReloadingMapTexture;
};
class LLFacebookFriendsPanel : public LLPanel, public LLFriendObserver
{
public:
LLFacebookFriendsPanel();
~LLFacebookFriendsPanel();
BOOL postBuild();
virtual void changed(U32 mask);
private:
bool updateSuggestedFriendList();
void showFriendsAccordionsIfNeeded();
void updateFacebookList(bool visible);
bool onConnectedToFacebook(const LLSD& data);
LLTextBox * mFriendsStatusCaption;
LLAvatarList* mSecondLifeFriends;
LLAvatarList* mSuggestedFriends;
};
class LLFloaterFacebook : public LLFloater
{
public:
LLFloaterFacebook(const LLSD& key);
BOOL postBuild();
void draw();
void onClose(bool app_quitting);
void onCancel();
void showPhotoPanel();
private:
LLFacebookPhotoPanel* mFacebookPhotoPanel;
LLTextBox* mStatusErrorText;
LLTextBox* mStatusLoadingText;
LLUICtrl* mStatusLoadingIndicator;
};
#endif // LL_LLFLOATERFACEBOOK_H

View File

@ -1921,6 +1921,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
mLandingTypeCombo(NULL),
mSnapshotCtrl(NULL),
mLocationText(NULL),
mSeeAvatarsText(NULL),
mSetBtn(NULL),
mClearBtn(NULL),
mMatureCtrl(NULL),
@ -1967,6 +1968,14 @@ BOOL LLPanelLandOptions::postBuild()
mSeeAvatarsCtrl = getChild<LLCheckBoxCtrl>( "SeeAvatarsCheck");
childSetCommitCallback("SeeAvatarsCheck", onCommitAny, this);
mSeeAvatarsText = getChild<LLTextBox>("allow_see_label");
if (mSeeAvatarsText)
{
mSeeAvatarsText->setShowCursorHand(false);
mSeeAvatarsText->setSoundFlags(LLView::MOUSE_UP);
mSeeAvatarsText->setClickedCallback(boost::bind(&toggleSeeAvatars, this));
}
mCheckShowDirectory = getChild<LLCheckBoxCtrl>( "ShowDirectoryCheck");
childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
@ -2060,6 +2069,7 @@ void LLPanelLandOptions::refresh()
mSeeAvatarsCtrl->set(TRUE);
mSeeAvatarsCtrl->setEnabled(FALSE);
mSeeAvatarsText->setEnabled(FALSE);
mLandingTypeCombo->setCurrentByIndex(0);
mLandingTypeCombo->setEnabled(FALSE);
@ -2118,6 +2128,7 @@ void LLPanelLandOptions::refresh()
mSeeAvatarsCtrl->set(parcel->getSeeAVs());
mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
mSeeAvatarsText->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
GP_LAND_SET_LANDING_POINT);
@ -2408,7 +2419,16 @@ void LLPanelLandOptions::onClickClear(void* userdata)
self->refresh();
}
void LLPanelLandOptions::toggleSeeAvatars(void* userdata)
{
LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
if (self)
{
self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->toggle();
self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->setBtnFocus();
self->onCommitAny(NULL, userdata);
}
}
//---------------------------------------------------------------------------
// LLPanelLandAccess
//---------------------------------------------------------------------------

View File

@ -105,7 +105,7 @@ protected:
static void* createPanelLandAccess(void* data);
static void* createPanelLandExperiences(void* data);
static void* createPanelLandEnvironment(void* data);
static void* createPanelLandBan(void* data);
static void* createPanelLandBan(void* data);
protected:
@ -330,6 +330,7 @@ private:
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
static void onClickSet(void* userdata);
static void onClickClear(void* userdata);
static void toggleSeeAvatars(void* userdata);
private:
LLCheckBoxCtrl* mCheckEditObjects;
@ -348,6 +349,7 @@ private:
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mLocationText;
LLTextBox* mSeeAvatarsText;
LLButton* mSetBtn;
LLButton* mClearBtn;

View File

@ -325,6 +325,8 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("import_scale", onImportScaleCommit, this);
childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
getChild<LLLineEditor>("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL);
getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
@ -520,6 +522,16 @@ void LLFloaterModelPreview::onClickCalculateBtn()
mUploadBtn->setEnabled(false);
}
void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
{
// Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
if (input->isDirty()) // dirty will be reset after commit
{
toggleCalculateButton(true);
}
}
//static
void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
{

View File

@ -137,7 +137,9 @@ protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
void onDescriptionKeystroke(LLUICtrl*);
static void onImportScaleCommit(LLUICtrl*, void*);
static void onPelvisOffsetCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);

View File

@ -30,9 +30,7 @@
#include "llfloateroutfitsnapshot.h"
#include "llagent.h"
#include "llfacebookconnect.h"
#include "llfloaterreg.h"
#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"

View File

@ -28,9 +28,7 @@
#include "llfloatersnapshot.h"
#include "llfacebookconnect.h"
#include "llfloaterreg.h"
#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
@ -1242,11 +1240,10 @@ BOOL LLFloaterSnapshot::isWaitingState()
BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
{
LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter)
if (!initialized && !floater_flickr && !floater_twitter)
return FALSE;
BOOL changed = FALSE;

View File

@ -514,11 +514,6 @@ void LLFloaterTools::refresh()
selection_info << getString("status_selectcount", selection_args);
getChild<LLTextBox>("selection_count")->setText(selection_info.str());
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
childSetVisible("selection_count", have_selection);
childSetVisible("remaining_capacity", have_selection);
childSetVisible("selection_empty", !have_selection);
}

View File

@ -30,7 +30,6 @@
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "llhttpconstants.h"
#include "llfacebookconnect.h"
#include "llflickrconnect.h"
#include "lltwitterconnect.h"
#include "lllayoutstack.h"
@ -289,17 +288,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
//virtual
void LLFloaterWebContent::onClose(bool app_quitting)
{
// If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web");
if (fbc_web == this)
{
if (!LLFacebookConnect::instance().isConnected())
{
LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
}
}
// Same with Flickr
// If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
if (flickr_web == this)
@ -309,7 +298,7 @@ void LLFloaterWebContent::onClose(bool app_quitting)
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
}
}
// And Twitter
// Same with Twitter
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
if (twitter_web == this)
@ -380,13 +369,6 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
// The browser instance wants its window closed.
closeFloater();
}
else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
{
if (mCurrentURL.find("facebook.com/dialog/oauth") == std::string::npos) // HACK to fix ACME-1317 - Cho
{
geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
}
}
else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
{
const std::string text = self->getStatusText();

View File

@ -1033,6 +1033,9 @@ F32 gpu_benchmark()
//number of samples to take
const S32 samples = 64;
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
ShaderProfileHelper initProfile;
std::vector<LLRenderTarget> dest(count);
@ -1050,12 +1053,14 @@ F32 gpu_benchmark()
gGL.setColorMask(true, true);
LLGLDepthTest depth(GL_FALSE);
LLTimer alloc_timer;
alloc_timer.start();
for (U32 i = 0; i < count; ++i)
{
//allocate render targets and textures
if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
{
LL_WARNS() << "Failed to allocate render target." << LL_ENDL;
LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
@ -1067,12 +1072,20 @@ F32 gpu_benchmark()
if (!texHolder.bind(i))
{
// can use a dummy value mDummyTexUnit = new LLTexUnit(-1);
LL_WARNS() << "Failed to bind tex unit." << LL_ENDL;
LL_WARNS("Benchmark") << "Failed to bind tex unit." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
}
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
if (alloc_timer.getElapsedTimeF32() > time_limit)
{
// abandon the benchmark test
LL_WARNS("Benchmark") << "Allocation operation took longer then 30 seconds, stopping." << LL_ENDL;
delete[] pixels;
return -1.f;
}
}
delete [] pixels;
@ -1082,7 +1095,7 @@ F32 gpu_benchmark()
if (!buff->allocateBuffer(3, 0, true))
{
LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL;
LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL;
// abandon the benchmark test
return -1.f;
}
@ -1092,7 +1105,7 @@ F32 gpu_benchmark()
if (! buff->getVertexStrider(v))
{
LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, "
LL_WARNS("Benchmark") << "GL LLVertexBuffer::getVertexStrider() returned false, "
<< "buff->getMappedData() is"
<< (buff->getMappedData()? " not" : "")
<< " NULL" << LL_ENDL;
@ -1113,7 +1126,8 @@ F32 gpu_benchmark()
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
for (S32 c = -1; c < samples; ++c)
F32 time_passed = 0; // seconds
for (S32 c = -1; c < samples && time_passed < time_limit; ++c)
{
LLTimer timer;
timer.start();
@ -1130,6 +1144,7 @@ F32 gpu_benchmark()
glFinish();
F32 time = timer.getElapsedTimeF32();
time_passed += time;
if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
{
@ -1144,12 +1159,12 @@ F32 gpu_benchmark()
F32 gbps = results[results.size()/2];
LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL;
LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
#if LL_DARWIN
if (gbps > 512.f)
{
LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
LL_WARNS("Benchmark") << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
//OSX is probably lying, discard result
return -1.f;
}
@ -1158,11 +1173,11 @@ F32 gpu_benchmark()
F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
F64 samples_drawn = res*res*count*samples;
F64 samples_drawn = res*res*count*results.size();
F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
gbps = samples_sec*8;
LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}

View File

@ -2137,6 +2137,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
static U32 lastGroupMemberRequestFrame = 0;
// Have we requested the information already this frame?
// Todo: make this per group, we can invite to one group and simultaneously be checking another one
if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
return;
@ -2166,6 +2167,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
return;
}
LLGroupMgrGroupData* group_datap = createGroupData(group_id); //make sure group exists
group_datap->mMemberRequestID.generate(); // mark as pending
lastGroupMemberRequestFrame = gFrameCount;
LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",

View File

@ -258,6 +258,11 @@ public:
bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
bool isMemberDataPending() { return mMemberRequestID.notNull(); }
bool isRoleDataPending() { return mRoleDataRequestID.notNull(); }
bool isRoleMemberDataPending() { return (mRoleMembersRequestID.notNull() || mPendingRoleMemberRequest); }
bool isGroupTitlePending() { return mTitlesRequestID.notNull(); }
bool isSingleMemberNotOwner();
F32 getAccessTime() const { return mAccessTime; }

View File

@ -1403,13 +1403,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
// Only should happen for broken links.
new_listener = new LLLinkItemBridge(inventory, root, uuid);
break;
case LLAssetType::AT_MESH:
if(!(inv_type == LLInventoryType::IT_MESH))
{
LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
}
new_listener = new LLMeshBridge(inventory, root, uuid);
break;
case LLAssetType::AT_UNKNOWN:
new_listener = new LLUnknownItemBridge(inventory, root, uuid);
break;
@ -2113,7 +2106,9 @@ BOOL LLItemBridge::isItemCopyable() const
LLViewerInventoryItem* item = getItem();
if (item)
{
// Can't copy worn objects. DEV-15183
// Can't copy worn objects.
// Worn objects are tied to their inworld conterparts
// Copy of modified worn object will return object with obsolete asset and inventory
if(get_is_item_worn(mUUID))
{
return FALSE;
@ -6857,58 +6852,6 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
// +=================================================+
// | LLMeshBridge |
// +=================================================+
LLUIImagePtr LLMeshBridge::getIcon() const
{
return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
}
void LLMeshBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
if (item)
{
// open mesh
}
}
void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
LL_DEBUGS() << "LLMeshBridge::buildContextMenu()" << LL_ENDL;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
if(isItemInTrash())
{
items.push_back(std::string("Purge Item"));
if (!isItemRemovable())
{
disabled_items.push_back(std::string("Purge Item"));
}
items.push_back(std::string("Restore Item"));
}
else if (isMarketplaceListingsFolder())
{
addMarketplaceContextMenuOptions(flags, items, disabled_items);
items.push_back(std::string("Properties"));
getClipboardEntries(false, items, disabled_items, flags);
}
else
{
items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
}
addLinkReplaceMenuOption(items, disabled_items);
hide_context_entries(menu, items, disabled_items);
}
// +=================================================+
// | LLSettingsBridge |
// +=================================================+

View File

@ -607,22 +607,6 @@ protected:
};
class LLMeshBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
protected:
LLMeshBridge(LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid) :
LLItemBridge(inventory, root, uuid) {}
};
class LLSettingsBridge : public LLItemBridge
{
public:
@ -677,17 +661,6 @@ protected:
LLInventoryModel* mModel;
};
class LLMeshBridgeAction: public LLInvFVBridgeAction
{
friend class LLInvFVBridgeAction;
public:
virtual void doIt() ;
virtual ~LLMeshBridgeAction(){}
protected:
LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Recent Inventory Panel related classes

View File

@ -59,6 +59,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
mHoursAgo(p.hours_ago),
mDateSearchDirection(p.date_search_direction),
mShowFolderState(p.show_folder_state),
mFilterCreatorType(p.creator_type),
mPermissions(p.permissions),
mFilterTypes(p.types),
mFilterUUID(p.uuid),
@ -79,8 +80,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
mCurrentGeneration(0),
mFirstRequiredGeneration(0),
mFirstSuccessGeneration(0),
mSearchType(SEARCHTYPE_NAME),
mFilterCreatorType(FILTERCREATOR_ALL)
mSearchType(SEARCHTYPE_NAME)
{
// copy mFilterOps into mDefaultFilterOps
markDefault();
@ -341,10 +341,10 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
LLSettingsType::type_e type = listener->getSettingsType();
if ((object_type == LLInventoryType::IT_SETTINGS) &&
(((0x1LL << type) & mFilterOps.mFilterSettingsTypes) == 0))
{
return FALSE;
}
}
{
return FALSE;
}
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_EMPTYFOLDERS
@ -504,7 +504,7 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
{
if (!listener) return TRUE;
const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
switch(mFilterCreatorType)
switch (mFilterOps.mFilterCreatorType)
{
case FILTERCREATOR_SELF:
if(is_folder) return FALSE;
@ -616,9 +616,9 @@ void LLInventoryFilter::setSearchType(ESearchType type)
void LLInventoryFilter::setFilterCreator(EFilterCreatorType type)
{
if(mFilterCreatorType != type)
if (mFilterOps.mFilterCreatorType != type)
{
mFilterCreatorType = type;
mFilterOps.mFilterCreatorType = type;
setModified();
}
}
@ -1215,6 +1215,7 @@ void LLInventoryFilter::toParams(Params& params) const
params.filter_ops.hours_ago = getHoursAgo();
params.filter_ops.date_search_direction = getDateSearchDirection();
params.filter_ops.show_folder_state = getShowFolderState();
params.filter_ops.creator_type = getFilterCreatorType();
params.filter_ops.permissions = getFilterPermissions();
params.substring = getFilterSubString();
params.since_logoff = isSinceLogoff();
@ -1237,6 +1238,7 @@ void LLInventoryFilter::fromParams(const Params& params)
setHoursAgo(params.filter_ops.hours_ago);
setDateSearchDirection(params.filter_ops.date_search_direction);
setShowFolderState(params.filter_ops.show_folder_state);
setFilterCreator(params.filter_ops.creator_type);
setFilterPermissions(params.filter_ops.permissions);
setFilterSubString(params.substring);
setDateRangeLastLogoff(params.since_logoff);
@ -1304,6 +1306,11 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
return mFilterOps.mShowFolderState;
}
LLInventoryFilter::EFilterCreatorType LLInventoryFilter::getFilterCreatorType() const
{
return mFilterOps.mFilterCreatorType;
}
bool LLInventoryFilter::isTimedOut()
{
return mFilterTime.hasExpired();

View File

@ -47,18 +47,18 @@ public:
enum EFilterType {
FILTERTYPE_NONE = 0,
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5, // pass if folder is not a system folder to be hidden if empty
FILTERTYPE_MARKETPLACE_ACTIVE = 0x1 << 6, // pass if folder is a marketplace active folder
FILTERTYPE_MARKETPLACE_INACTIVE = 0x1 << 7, // pass if folder is a marketplace inactive folder
FILTERTYPE_MARKETPLACE_UNASSOCIATED = 0x1 << 8, // pass if folder is a marketplace non associated (no market ID) folder
FILTERTYPE_MARKETPLACE_LISTING_FOLDER = 0x1 << 9, // pass iff folder is a listing folder
FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10, // pass iff folder is not under the marketplace
FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn
FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn
FILTERTYPE_SETTINGS = 0x1 << 12, // pass if the item is a settings object
};
@ -128,19 +128,21 @@ public:
Optional<U32> date_search_direction;
Optional<EFolderShow> show_folder_state;
Optional<PermissionMask> permissions;
Optional<EFilterCreatorType> creator_type;
Params()
: types("filter_types", FILTERTYPE_OBJECT),
object_types("object_types", 0xffffFFFFffffFFFFULL),
wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
settings_types("settings_types", 0xffffFFFFffffFFFFULL),
category_types("category_types", 0xffffFFFFffffFFFFULL),
category_types("category_types", 0xffffFFFFffffFFFFULL),
links("links", FILTERLINK_INCLUDE_LINKS),
uuid("uuid"),
date_range("date_range"),
hours_ago("hours_ago", 0),
date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER),
show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
creator_type("creator_type", FILTERCREATOR_ALL),
permissions("permissions", PERM_NONE)
{}
};
@ -148,11 +150,11 @@ public:
FilterOps(const Params& = Params());
U32 mFilterTypes;
U64 mFilterObjectTypes, // For _OBJECT
mFilterWearableTypes,
U64 mFilterObjectTypes, // For _OBJECT
mFilterWearableTypes,
mFilterSettingsTypes, // for _SETTINGS
mFilterLinks,
mFilterCategoryTypes; // For _CATEGORY
mFilterLinks,
mFilterCategoryTypes; // For _CATEGORY
LLUUID mFilterUUID; // for UUID
time_t mMinDate,
@ -162,6 +164,7 @@ public:
EFolderShow mShowFolderState;
PermissionMask mPermissions;
EFilterCreatorType mFilterCreatorType;
};
struct Params : public LLInitParam::Block<Params>
@ -209,7 +212,6 @@ public:
void setSearchType(ESearchType type);
ESearchType getSearchType() { return mSearchType; }
void setFilterCreator(EFilterCreatorType type);
EFilterCreatorType getFilterCreator() { return mFilterCreatorType; }
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
@ -252,6 +254,7 @@ public:
// +-------------------------------------------------------------------+
void setShowFolderState( EFolderShow state);
EFolderShow getShowFolderState() const;
EFilterCreatorType getFilterCreatorType() const;
void setEmptyLookupMessage(const std::string& message);
std::string getEmptyLookupMessage() const;
@ -331,7 +334,6 @@ private:
std::string mEmptyLookupMessage;
ESearchType mSearchType;
EFilterCreatorType mFilterCreatorType;
};
#endif

View File

@ -888,13 +888,10 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
return mask;
}
// We're hiding mesh types
#if 0
if (item->getType() == LLAssetType::AT_MESH)
{
return mask;
}
#endif
LLPointer<LLViewerInventoryItem> old_item = getItem(item->getUUID());
LLPointer<LLViewerInventoryItem> new_item;

View File

@ -65,11 +65,11 @@ public:
S32 LLMachineID::init()
{
memset(static_unique_id,0,sizeof(static_unique_id));
size_t len = sizeof(static_unique_id);
memset(static_unique_id, 0, len);
S32 ret_code = 0;
#if LL_WINDOWS
# pragma comment(lib, "wbemuuid.lib")
size_t len = sizeof(static_unique_id);
// algorithm to detect BIOS serial number found at:
// http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
@ -217,15 +217,25 @@ S32 LLMachineID::init()
// Get the value of the Name property
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
if (FAILED(hr))
{
LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL;
pclsObj->Release();
pclsObj = NULL;
continue;
}
LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
// use characters in the returned Serial Number to create a byte array of size len
BSTR serialNumber ( vtProp.bstrVal);
unsigned int serial_size = SysStringLen(serialNumber);
unsigned int j = 0;
while( vtProp.bstrVal[j] != 0)
while (j < serial_size && vtProp.bstrVal[j] != 0)
{
for (unsigned int i = 0; i < len; i++)
{
if (vtProp.bstrVal[j] == 0)
if (j >= serial_size || vtProp.bstrVal[j] == 0)
break;
static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
@ -254,6 +264,21 @@ S32 LLMachineID::init()
ret_code = LLUUID::getNodeID(staticPtr);
#endif
has_static_unique_id = true;
LL_INFOS("AppInit") << "UniqueID: 0x";
// Code between here and LL_ENDL is not executed unless the LL_DEBUGS
// actually produces output
for (size_t i = 0; i < len; ++i)
{
// Copy each char to unsigned int to hexify. Sending an unsigned
// char to a std::ostream tries to represent it as a char, not
// what we want here.
unsigned byte = static_unique_id[i];
LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
}
// Reset default output formatting to avoid nasty surprises!
LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
return ret_code;
}
@ -263,21 +288,6 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
if (has_static_unique_id)
{
memcpy ( unique_id, &static_unique_id, len);
#if LL_LOG_MACHINE_ID
LL_INFOS_ONCE("AppInit") << "UniqueID: 0x";
// Code between here and LL_ENDL is not executed unless the LL_DEBUGS
// actually produces output
for (size_t i = 0; i < len; ++i)
{
// Copy each char to unsigned int to hexify. Sending an unsigned
// char to a std::ostream tries to represent it as a char, not
// what we want here.
unsigned byte = unique_id[i];
LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
}
// Reset default output formatting to avoid nasty surprises!
LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
#endif
return 1;
}
return 0;

View File

@ -34,6 +34,7 @@
#include "llcachename.h"
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llfloatersnapshot.h" // gSnapshotFloaterView
#include "llinventory.h"
#include "llscrolllistitem.h"
#include "llscrolllistcell.h"
@ -236,24 +237,30 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
// Spawn at right side of cell
LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
S32 screenX = sticky_rect.mRight - info_icon_size;
S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;
LLCoordGL pos(screenX, screenY);
// Should we show a group or an avatar inspector?
bool is_group = hit_item->isGroup();
bool is_experience = hit_item->isExperience();
LLFloater* snapshot_floatr = gSnapshotFloaterView->getFrontmostClosableFloater();
if (!snapshot_floatr || !snapshot_floatr->getRect().pointInRect(screenX + icon->getWidth(), screenY))
{
// Should we show a group or an avatar inspector?
bool is_group = hit_item->isGroup();
bool is_experience = hit_item->isExperience();
LLToolTip::Params params;
params.background_visible( false );
params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) );
params.delay_time(0.0f); // spawn instantly on hover
params.image( icon );
params.message("");
params.padding(0);
params.pos(pos);
params.sticky_rect(sticky_rect);
LLToolTip::Params params;
params.background_visible(false);
params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience));
params.delay_time(0.0f); // spawn instantly on hover
params.image(icon);
params.message("");
params.padding(0);
params.pos(pos);
params.sticky_rect(sticky_rect);
LLToolTipMgr::getInstance()->show(params);
handled = TRUE;
LLToolTipMgr::getInstance()->show(params);
handled = TRUE;
}
}
}
}

View File

@ -35,7 +35,6 @@
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llscriptfloater.h"
#include "llfacebookconnect.h"
#include "llavatarname.h"
#include "llavatarnamecache.h"

View File

@ -89,7 +89,7 @@ BOOL LLPanelExperiencePicker::postBuild()
childSetAction(BTN_PROFILE, boost::bind(&LLPanelExperiencePicker::onBtnProfile, this));
getChildView(BTN_PROFILE)->setEnabled(FALSE);
getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(2);
getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(gSavedPerAccountSettings.getU32("ExperienceSearchMaturity"));
getChild<LLComboBox>(TEXT_MATURITY)->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onMaturity, this));
getChild<LLUICtrl>(TEXT_EDIT)->setFocus(TRUE);
@ -381,6 +381,7 @@ void LLPanelExperiencePicker::filterContent()
void LLPanelExperiencePicker::onMaturity()
{
gSavedPerAccountSettings.setU32("ExperienceSearchMaturity", getChild<LLComboBox>(TEXT_MATURITY)->getCurrentIndex());
if(mResponse.has("experience_keys") && mResponse["experience_keys"].beginArray() != mResponse["experience_keys"].endArray())
{
filterContent();

View File

@ -606,11 +606,30 @@ void LLPanelGroupInvite::updateLists()
{
if (!mPendingUpdate)
{
// Note: this will partially fail if some requests are already in progress
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
}
else if (gdatap)
{
// restart requests that were interrupted/dropped/failed to start
if (!gdatap->isRoleDataPending() && !gdatap->isRoleDataComplete())
{
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
}
if (!gdatap->isRoleMemberDataPending() && !gdatap->isRoleMemberDataComplete())
{
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
}
// sendCapGroupMembersRequest has a per frame send limitation that could have
// interrupted previous request
if (!gdatap->isMemberDataPending() && !gdatap->isMemberDataComplete())
{
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
}
}
mPendingUpdate = TRUE;
}
else

View File

@ -1962,6 +1962,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
mRoleDescription(NULL),
mMemberVisibleCheck(NULL),
mDeleteRoleButton(NULL),
mCopyRoleButton(NULL),
mCreateRoleButton(NULL),
mFirstOpen(TRUE),
mHasRoleChange(FALSE)
@ -2012,6 +2013,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mCreateRoleButton->setClickedCallback(onCreateRole, this);
mCreateRoleButton->setEnabled(FALSE);
}
mCopyRoleButton =
parent->getChild<LLButton>("role_copy", recurse);
if ( mCopyRoleButton )
{
mCopyRoleButton->setClickedCallback(onCopyRole, this);
mCopyRoleButton->setEnabled(FALSE);
}
mDeleteRoleButton =
parent->getChild<LLButton>("role_delete", recurse);
@ -2226,6 +2235,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
mRoleTitle->clear();
setFooterEnabled(FALSE);
mDeleteRoleButton->setEnabled(FALSE);
mCopyRoleButton->setEnabled(FALSE);
}
}
@ -2336,6 +2346,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
mSelectedRole = item->getUUID();
buildMembersList();
mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE));
can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID,
GP_ROLE_DELETE);
mDeleteRoleButton->setEnabled(can_delete);
@ -2661,6 +2672,57 @@ void LLPanelGroupRolesSubTab::handleCreateRole()
notifyObservers();
}
// static
void LLPanelGroupRolesSubTab::onCopyRole(void* user_data)
{
LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
if (!self) return;
self->handleCopyRole();
}
void LLPanelGroupRolesSubTab::handleCopyRole()
{
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap) return;
LLScrollListItem* role_item = mRolesList->getFirstSelected();
if (!role_item || role_item->getUUID().isNull())
{
return;
}
LLRoleData rd;
if (!gdatap->getRoleData(role_item->getUUID(), rd))
{
return;
}
LLUUID new_role_id;
new_role_id.generate();
rd.mRoleName += "(Copy)";
gdatap->createRole(new_role_id,rd);
mRolesList->deselectAllItems(TRUE);
LLSD row;
row["id"] = new_role_id;
row["columns"][0]["column"] = "name";
row["columns"][0]["value"] = rd.mRoleName;
mRolesList->addElement(row, ADD_BOTTOM, this);
mRolesList->selectByID(new_role_id);
// put focus on name field and select its contents
if(mRoleName)
{
mRoleName->setFocus(TRUE);
mRoleName->onTabInto();
gFocusMgr.triggerFocusFlash();
}
notifyObservers();
}
// static
void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data)
{

View File

@ -269,6 +269,9 @@ public:
static void onCreateRole(void*);
void handleCreateRole();
static void onCopyRole(void*);
void handleCopyRole();
static void onDeleteRole(void*);
void handleDeleteRole();
@ -296,6 +299,7 @@ protected:
LLCheckBoxCtrl* mMemberVisibleCheck;
LLButton* mDeleteRoleButton;
LLButton* mCreateRoleButton;
LLButton* mCopyRoleButton;
LLUUID mSelectedRole;
BOOL mHasRoleChange;

View File

@ -178,7 +178,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mPasswordModified = FALSE;
LLPanelLogin::sInstance = this;
sInstance = this;
LLView* login_holder = gViewerWindow->getLoginPanelHolder();
if (login_holder)
@ -234,29 +234,44 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();
server_choice_combo->selectFirstItem();
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
// argument (CmdLineLoginLocation) or by default.
// current_grid might have been set either by an explicit command-line
// argument (CmdLineGridChoice) or by default.
// If the grid specified by StartSLURL is the same as current_grid, the
// distinction is moot.
// If we have an explicit command-line SLURL, use that.
// If we DON'T have an explicit command-line SLURL but we DO have an
// explicit command-line grid, which is different from the default SLURL's
// -- do NOT override the explicit command-line grid with the grid from
// the default SLURL!
bool force_grid{ start_slurl.getGrid() != current_grid &&
gSavedSettings.getString("CmdLineLoginLocation").empty() &&
! gSavedSettings.getString("CmdLineGridChoice").empty() };
if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
{
// no, so get the preference setting
std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL;
LLSLURL defaultStart(defaultStartLocation);
if ( defaultStart.isSpatial() )
if ( defaultStart.isSpatial() && ! force_grid )
{
LLStartUp::setStartSLURL(defaultStart);
}
else
{
LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL;
LL_INFOS("AppInit") << (force_grid? "--grid specified" : "no valid LoginLocation")
<< ", using home" << LL_ENDL;
LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME);
LLStartUp::setStartSLURL(homeStart);
}
}
else
else if (! force_grid)
{
LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
onUpdateStartSLURL(start_slurl); // updates grid if needed
}
childSetAction("connect_btn", onClickConnect, this);
@ -380,7 +395,7 @@ void LLPanelLogin::setFocus(BOOL b)
{
if(b)
{
LLPanelLogin::giveFocus();
giveFocus();
}
else
{
@ -748,7 +763,10 @@ void LLPanelLogin::closePanel()
{
if (sInstance)
{
LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
if (LLPanelLogin::sInstance->getParent())
{
LLPanelLogin::sInstance->getParent()->removeChild(LLPanelLogin::sInstance);
}
delete sInstance;
sInstance = NULL;

View File

@ -889,7 +889,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
U32 hours = mFilter->getHoursAgo();
U32 date_search_direction = mFilter->getDateSearchDirection();
LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreator();
LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType();
bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF));
bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS));
@ -902,7 +902,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
getChild<LLUICtrl>("check_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@ -959,12 +958,6 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_mesh")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_MESH);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@ -1119,13 +1112,12 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
self->getChild<LLUICtrl>("check_mesh")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
self->getChild<LLUICtrl>("check_sound")->setValue(TRUE);
self->getChild<LLUICtrl>("check_texture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
self->getChild<LLUICtrl>("check_settings")->setValue(TRUE);
}
@ -1140,7 +1132,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
self->getChild<LLUICtrl>("check_mesh")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);

View File

@ -1123,92 +1123,6 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const
return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );
}
///----------------------------------------------------------------------------
/// Class LLTaskMeshBridge
///----------------------------------------------------------------------------
class LLTaskMeshBridge : public LLTaskInvFVBridge
{
public:
LLTaskMeshBridge(
LLPanelObjectInventory* panel,
const LLUUID& uuid,
const std::string& name);
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
};
LLTaskMeshBridge::LLTaskMeshBridge(
LLPanelObjectInventory* panel,
const LLUUID& uuid,
const std::string& name) :
LLTaskInvFVBridge(panel, uuid, name)
{
}
LLUIImagePtr LLTaskMeshBridge::getIcon() const
{
return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
}
void LLTaskMeshBridge::openItem()
{
// open mesh
}
// virtual
void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action)
{
if (action == "mesh action")
{
LLInventoryItem* item = findItem();
if(item)
{
// do action
}
}
LLTaskInvFVBridge::performAction(model, action);
}
void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
LLInventoryItem* item = findItem();
std::vector<std::string> items;
std::vector<std::string> disabled_items;
if(!item)
{
hide_context_entries(menu, items, disabled_items);
return;
}
items.push_back(std::string("Task Open"));
if (!isItemCopyable())
{
disabled_items.push_back(std::string("Task Open"));
}
items.push_back(std::string("Task Properties"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
disabled_items.push_back(std::string("Task Properties"));
}
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));
}
if(isItemRemovable())
{
items.push_back(std::string("Task Remove"));
}
hide_context_entries(menu, items, disabled_items);
}
///----------------------------------------------------------------------------
/// Class LLTaskSettingsBridge
///----------------------------------------------------------------------------
@ -1236,7 +1150,6 @@ LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
return LLSettingsType::ST_NONE;
}
///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@ -1318,11 +1231,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_id,
object_name);
break;
case LLAssetType::AT_MESH:
new_bridge = new LLTaskMeshBridge(panel,
object_id,
object_name);
break;
case LLAssetType::AT_SETTINGS:
new_bridge = new LLTaskSettingsBridge(panel,
object_id,
@ -1534,7 +1442,14 @@ void LLPanelObjectInventory::updateInventory()
mIsInventoryEmpty = TRUE;
}
mHaveInventory = TRUE;
mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty();
if (objectp->isInventoryDirty())
{
// Inventory is dirty, yet we received inventoryChanged() callback.
// User changed something during ongoing request.
// Rerequest. It will clear dirty flag and won't create dupplicate requests.
objectp->requestInventory();
}
}
else
{
@ -1804,7 +1719,7 @@ void LLPanelObjectInventory::deleteAllChildren()
BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
{
if (mFolders && mHaveInventory)
if (mFolders)
{
LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
if (!folderp)

View File

@ -106,9 +106,9 @@ private:
LLUUID mTaskUUID;
LLUUID mAttachmentUUID;
BOOL mHaveInventory;
BOOL mIsInventoryEmpty;
BOOL mInventoryNeedsUpdate;
BOOL mHaveInventory; // 'Loading' label and used for initial request
BOOL mIsInventoryEmpty; // 'Empty' label
BOOL mInventoryNeedsUpdate; // for idle, set on changed callback
LLFolderViewModelInventory mInventoryViewModel;
};

View File

@ -54,7 +54,6 @@
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcallbacklist.h"
#include "llerror.h"
#include "llfacebookconnect.h"
#include "llfloateravatarpicker.h"
#include "llfriendcard.h"
#include "llgroupactions.h"
@ -537,7 +536,6 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
mTryToConnectToFacebook(true),
mTabContainer(NULL),
mOnlineFriendList(NULL),
mAllFriendList(NULL),
@ -645,11 +643,9 @@ BOOL LLPanelPeople::postBuild()
// updater is active only if panel is visible to user.
friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::updateFacebookList, this, _2));
mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
mSuggestedFriends = friends_tab->getChild<LLAvatarList>("suggested_friends");
mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
mOnlineFriendList->setShowIcons("FriendsListShowIcons");
mOnlineFriendList->showPermissions("FriendsListShowPermissions");
@ -685,7 +681,6 @@ BOOL LLPanelPeople::postBuild()
mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false);
setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false);
@ -764,7 +759,7 @@ void LLPanelPeople::updateFriendListHelpText()
// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches() || mSuggestedFriends->filterHasMatches();
bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches();
no_friends_text->setVisible(!any_friend_exists);
if (no_friends_text->getVisible())
{
@ -831,40 +826,9 @@ void LLPanelPeople::updateFriendList()
mAllFriendList->setDirty(true, !mAllFriendList->filterHasMatches());
//update trash and other buttons according to a selected item
updateButtons();
updateSuggestedFriendList();
showFriendsAccordionsIfNeeded();
}
bool LLPanelPeople::updateSuggestedFriendList()
{
const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
suggested_friends.clear();
//Add suggested friends
LLSD friends = LLFacebookConnect::instance().getContent();
for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
{
LLUUID agent_id = (*i).asUUID();
bool second_life_buddy = agent_id.notNull() ? av_tracker.isBuddy(agent_id) : false;
if(!second_life_buddy)
{
//FB+SL but not SL friend
if (agent_id.notNull())
{
suggested_friends.push_back(agent_id);
}
}
}
//Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
showFriendsAccordionsIfNeeded();
return false;
}
void LLPanelPeople::updateNearbyList()
{
if (!mNearbyList)
@ -888,51 +852,6 @@ void LLPanelPeople::updateRecentList()
mRecentList->setDirty();
}
bool LLPanelPeople::onConnectedToFacebook(const LLSD& data)
{
LLSD::Integer connection_state = data.get("enum").asInteger();
if (connection_state == LLFacebookConnect::FB_CONNECTED)
{
LLFacebookConnect::instance().loadFacebookFriends();
}
else if(connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
{
updateSuggestedFriendList();
};
return false;
}
void LLPanelPeople::updateFacebookList(bool visible)
{
if (visible)
{
LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); // just in case it is already listening
LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLPanelPeople", boost::bind(&LLPanelPeople::updateSuggestedFriendList, this));
LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); // just in case it is already listening
LLEventPumps::instance().obtain("FacebookConnectState").listen("LLPanelPeople", boost::bind(&LLPanelPeople::onConnectedToFacebook, this, _1));
if (LLFacebookConnect::instance().isConnected())
{
LLFacebookConnect::instance().loadFacebookFriends();
}
else if(mTryToConnectToFacebook)
{
LLFacebookConnect::instance().checkConnectionToFacebook();
mTryToConnectToFacebook = false;
}
updateSuggestedFriendList();
}
else
{
LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople");
LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople");
}
}
void LLPanelPeople::updateButtons()
{
std::string cur_tab = getActiveTabName();
@ -1151,11 +1070,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
mOnlineFriendList->setNameFilter(filter);
mAllFriendList->setNameFilter(filter);
mSuggestedFriends->setNameFilter(filter);
setAccordionCollapsedByUser("tab_online", false);
setAccordionCollapsedByUser("tab_all", false);
setAccordionCollapsedByUser("tab_suggested_friends", false);
showFriendsAccordionsIfNeeded();
// restore accordion tabs state _after_ all manipulations
@ -1600,7 +1517,6 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()
// Expand and show accordions if needed, else - hide them
showAccordion("tab_online", mOnlineFriendList->filterHasMatches());
showAccordion("tab_all", mAllFriendList->filterHasMatches());
showAccordion("tab_suggested_friends", mSuggestedFriends->filterHasMatches());
// Rearrange accordions
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");

View File

@ -57,8 +57,6 @@ public:
// when voice is available
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
bool mTryToConnectToFacebook;
// internals
class Updater;
@ -80,10 +78,8 @@ private:
// methods indirectly called by the updaters
void updateFriendListHelpText();
void updateFriendList();
bool updateSuggestedFriendList();
void updateNearbyList();
void updateRecentList();
void updateFacebookList(bool visible);
bool isItemsFreeOfFriends(const uuid_vec_t& uuids);
@ -131,8 +127,6 @@ private:
void onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param);
bool onConnectedToFacebook(const LLSD& data);
void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
void setAccordionCollapsedByUser(const std::string& name, bool collapsed);
bool isAccordionCollapsedByUser(LLUICtrl* acc_tab);
@ -141,7 +135,6 @@ private:
LLTabContainer* mTabContainer;
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
LLAvatarList* mSuggestedFriends;
LLAvatarList* mNearbyList;
LLAvatarList* mRecentList;
LLGroupList* mGroupList;

View File

@ -52,7 +52,6 @@ namespace LLPanelPeopleMenus
PeopleContextMenu gPeopleContextMenu;
NearbyPeopleContextMenu gNearbyPeopleContextMenu;
SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
//== PeopleContextMenu ===============================================================
@ -413,36 +412,4 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
//== SuggestedFriendsContextMenu ===============================================================
LLContextMenu* SuggestedFriendsContextMenu::createMenu()
{
// set up the callbacks for all of the avatar menu items
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
LLContextMenu* menu;
// Set up for one person selected menu
const LLUUID& id = mUUIDs.front();
registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id));
registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id));
// create the context menu from the XUI
menu = createFromFile("menu_people_nearby.xml");
buildContextMenu(*menu, 0x0);
return menu;
}
void SuggestedFriendsContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
{
menuentry_vec_t items;
menuentry_vec_t disabled_items;
items.push_back(std::string("view_profile"));
items.push_back(std::string("add_friend"));
hide_context_entries(menu, items, disabled_items);
}
} // namespace LLPanelPeopleMenus

View File

@ -62,21 +62,8 @@ protected:
/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
};
/**
* Menu used in the suggested friends list.
*/
class SuggestedFriendsContextMenu : public PeopleContextMenu
{
public:
/*virtual*/ LLContextMenu * createMenu();
protected:
/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
};
extern PeopleContextMenu gPeopleContextMenu;
extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
extern SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
} // namespace LLPanelPeopleMenus

View File

@ -563,11 +563,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
mSaleToText->setText(getString("anyone"));
}
const U8* sign = (U8*)getString("price_text").c_str();
const U8* sqm = (U8*)getString("area_text").c_str();
mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice()));
mAreaText->setText(llformat("%d %s", area, sqm));
mSalesPriceText->setText(llformat("%s%d ", getString("price_text").c_str(), parcel->getSalePrice()));
mAreaText->setText(llformat("%d %s", area, getString("area_text").c_str()));
mTrafficText->setText(llformat("%.0f", dwell));
// Can't have more than region max tasks, regardless of parcel
@ -575,10 +572,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
S32 primitives = llmin(ll_round(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()),
(S32)region->getMaxTasks());
const U8* available = (U8*)getString("available").c_str();
const U8* allocated = (U8*)getString("allocated").c_str();
mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated));
mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, getString("available").c_str(), parcel->getPrimCount(), getString("allocated").c_str()));
if (parcel->getAllowOtherScripts())
{

View File

@ -32,7 +32,6 @@
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
#include "llfloaterreg.h"
#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
@ -59,7 +58,6 @@ private:
void onSaveToEmail();
void onSaveToInventory();
void onSaveToComputer();
void onSendToFacebook();
void onSendToTwitter();
void onSendToFlickr();
@ -74,7 +72,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
mCommitCallbackRegistrar.add("Snapshot.SendToFacebook", boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this));
mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
LLGlobalEconomy::getInstance()->addObserver(this);
@ -138,18 +135,6 @@ void LLPanelSnapshotOptions::onSaveToComputer()
openPanel("panel_snapshot_local");
}
void LLPanelSnapshotOptions::onSendToFacebook()
{
LLFloaterReg::hideInstance("snapshot");
LLFloaterFacebook* facebook_floater = dynamic_cast<LLFloaterFacebook*>(LLFloaterReg::getInstance("facebook"));
if (facebook_floater)
{
facebook_floater->showPhotoPanel();
}
LLFloaterReg::showInstance("facebook");
}
void LLPanelSnapshotOptions::onSendToTwitter()
{
LLFloaterReg::hideInstance("snapshot");

View File

@ -32,6 +32,7 @@
#include "llagent.h"
#include "lldraghandle.h"
#include "llexternaleditor.h"
#include "llviewerwindow.h"
#include "llbutton.h"
#include "llfloaterreg.h"
@ -43,6 +44,7 @@
#include "roles_constants.h"
#include "llscrollbar.h"
#include "llselectmgr.h"
#include "lltrans.h"
#include "llviewertexteditor.h"
#include "llvfile.h"
#include "llviewerinventory.h"
@ -63,7 +65,8 @@
// Default constructor
LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
: LLPreview( key )
: LLPreview( key ),
mLiveFile(NULL)
{
const LLInventoryItem *item = getItem();
if (item)
@ -74,13 +77,14 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
LLPreviewNotecard::~LLPreviewNotecard()
{
delete mLiveFile;
}
BOOL LLPreviewNotecard::postBuild()
{
LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
ed->makePristine();
mEditor = getChild<LLViewerTextEditor>("Notecard Editor");
mEditor->setNotecardInfo(mItemUUID, mObjectID, getKey());
mEditor->makePristine();
childSetAction("Save", onClickSave, this);
getChildView("lock")->setVisible( FALSE);
@ -88,6 +92,8 @@ BOOL LLPreviewNotecard::postBuild()
childSetAction("Delete", onClickDelete, this);
getChildView("Delete")->setEnabled(false);
childSetAction("Edit", onClickEdit, this);
const LLInventoryItem* item = getItem();
childSetCommitCallback("desc", LLPreview::onText, this);
@ -110,15 +116,13 @@ bool LLPreviewNotecard::saveItem()
void LLPreviewNotecard::setEnabled( BOOL enabled )
{
LLViewerTextEditor* editor = findChild<LLViewerTextEditor>("Notecard Editor");
// editor is part of xml, if it doesn't exists, nothing else does
if (editor)
{
editor->setEnabled(enabled);
getChildView("lock")->setVisible( !enabled);
getChildView("desc")->setEnabled(enabled);
getChildView("Save")->setEnabled(enabled && (!editor->isPristine()));
}
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
getChildView("Notecard Editor")->setEnabled(enabled);
getChildView("lock")->setVisible( !enabled);
getChildView("desc")->setEnabled(enabled);
getChildView("Save")->setEnabled(enabled && editor && (!editor->isPristine()));
}
@ -410,6 +414,16 @@ void LLPreviewNotecard::onClickDelete(void* user_data)
}
}
// static
void LLPreviewNotecard::onClickEdit(void* user_data)
{
LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
if (preview)
{
preview->openInExternalEditor();
}
}
struct LLSaveNotecardInfo
{
LLPreviewNotecard* mSelf;
@ -470,7 +484,7 @@ void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUI
}
}
bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
{
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
@ -489,7 +503,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
}
editor->makePristine();
if (sync)
{
syncExternal();
}
const LLInventoryItem* item = getItem();
// save it out to database
if (item)
@ -573,6 +590,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
return true;
}
void LLPreviewNotecard::syncExternal()
{
// Sync with external editor.
std::string tmp_file = getTmpFileName();
llstat s;
if (LLFile::stat(tmp_file, &s) == 0) // file exists
{
if (mLiveFile) mLiveFile->ignoreNextUpdate();
writeToFile(tmp_file);
}
}
void LLPreviewNotecard::deleteNotecard()
{
LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2));
@ -721,4 +750,128 @@ bool LLPreviewNotecard::handleConfirmDeleteDialog(const LLSD& notification, cons
return false;
}
void LLPreviewNotecard::openInExternalEditor()
{
delete mLiveFile; // deletes file
// Save the notecard to a temporary file.
std::string filename = getTmpFileName();
writeToFile(filename);
// Start watching file changes.
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1));
mLiveFile->addToEventTimer();
// Open it in external editor.
{
LLExternalEditor ed;
LLExternalEditor::EErrorCode status;
std::string msg;
status = ed.setCommand("LL_SCRIPT_EDITOR");
if (status != LLExternalEditor::EC_SUCCESS)
{
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
msg = LLTrans::getString("ExternalEditorNotSet");
}
else
{
msg = LLExternalEditor::getErrorMessage(status);
}
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
return;
}
status = ed.run(filename);
if (status != LLExternalEditor::EC_SUCCESS)
{
msg = LLExternalEditor::getErrorMessage(status);
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
}
}
}
bool LLPreviewNotecard::onExternalChange(const std::string& filename)
{
if (!loadNotecardText(filename))
{
return false;
}
// Disable sync to avoid recursive load->save->load calls.
saveIfNeeded(NULL, false);
return true;
}
bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
{
if (filename.empty())
{
LL_WARNS() << "Empty file name" << LL_ENDL;
return false;
}
LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
return false;
}
// read in the whole file
fseek(file, 0L, SEEK_END);
size_t file_length = (size_t)ftell(file);
fseek(file, 0L, SEEK_SET);
char* buffer = new char[file_length + 1];
size_t nread = fread(buffer, 1, file_length, file);
if (nread < file_length)
{
LL_WARNS() << "Short read" << LL_ENDL;
}
buffer[nread] = '\0';
fclose(file);
mEditor->setText(LLStringExplicit(buffer));
delete[] buffer;
return true;
}
bool LLPreviewNotecard::writeToFile(const std::string& filename)
{
LLFILE* fp = LLFile::fopen(filename, "wb");
if (!fp)
{
LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
return false;
}
std::string utf8text = mEditor->getText();
if (utf8text.size() == 0)
{
utf8text = " ";
}
fputs(utf8text.c_str(), fp);
fclose(fp);
return true;
}
std::string LLPreviewNotecard::getTmpFileName()
{
std::string notecard_id = mObjectID.asString() + "_" + mItemUUID.asString();
// Use MD5 sum to make the file name shorter and not exceed maximum path length.
char notecard_id_hash_str[33]; /* Flawfinder: ignore */
LLMD5 notecard_id_hash((const U8 *)notecard_id.c_str());
notecard_id_hash.hex_digest(notecard_id_hash_str);
return std::string(LLFile::tmpdir()) + "sl_notecard_" + notecard_id_hash_str + ".txt";
}
// EOF

View File

@ -29,6 +29,7 @@
#include "llpreview.h"
#include "llassetstorage.h"
#include "llpreviewscript.h"
#include "lliconctrl.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -47,18 +48,18 @@ public:
virtual ~LLPreviewNotecard();
bool saveItem();
void setObjectID(const LLUUID& object_id);
void setObjectID(const LLUUID& object_id) override;
// llview
virtual void draw();
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void setEnabled( BOOL enabled );
void draw() override;
BOOL handleKeyHere(KEY key, MASK mask) override;
void setEnabled( BOOL enabled ) override;
// llfloater
virtual BOOL canClose();
BOOL canClose() override;
// llpanel
virtual BOOL postBuild();
BOOL postBuild() override;
// reach into the text editor, and grab the drag item
const LLInventoryItem* getDragItem();
@ -72,11 +73,13 @@ public:
// asset system. :(
void refreshFromInventory(const LLUUID& item_id = LLUUID::null);
void syncExternal();
protected:
void updateTitleButtons();
virtual void loadAsset();
bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
void updateTitleButtons() override;
void loadAsset() override;
bool saveIfNeeded(LLInventoryItem* copyitem = NULL, bool sync = true);
void deleteNotecard();
@ -89,6 +92,8 @@ protected:
static void onClickDelete(void* data);
static void onClickEdit(void* data);
static void onSaveComplete(const LLUUID& asset_uuid,
void* user_data,
S32 status, LLExtStat ext_status);
@ -99,6 +104,12 @@ protected:
static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
void openInExternalEditor();
bool onExternalChange(const std::string& filename);
bool loadNotecardText(const std::string& filename);
bool writeToFile(const std::string& filename);
std::string getTmpFileName();
protected:
LLViewerTextEditor* mEditor;
LLButton* mSaveBtn;
@ -106,6 +117,8 @@ protected:
LLUUID mAssetID;
LLUUID mObjectID;
LLLiveLSLFile* mLiveFile;
};

View File

@ -40,7 +40,6 @@
#include "llinventorymodel.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "lllivefile.h"
#include "llhelp.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
@ -119,22 +118,6 @@ static bool have_script_upload_cap(LLUUID& object_id)
/// ---------------------------------------------------------------------------
/// LLLiveLSLFile
/// ---------------------------------------------------------------------------
class LLLiveLSLFile : public LLLiveFile
{
public:
typedef boost::function<bool (const std::string& filename)> change_callback_t;
LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
~LLLiveLSLFile();
void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
protected:
/*virtual*/ bool loadFile();
change_callback_t mOnChangeCallback;
bool mIgnoreNextUpdate;
};
LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb)
: mOnChangeCallback(change_cb)
@ -1068,7 +1051,7 @@ void LLScriptEdCore::openInExternalEditor()
{
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
msg = getString("external_editor_not_set");
msg = LLTrans::getString("ExternalEditorNotSet");
}
else
{

View File

@ -34,6 +34,7 @@
#include "lliconctrl.h"
#include "llframetimer.h"
#include "llfloatergotoline.h"
#include "lllivefile.h"
#include "llsyntaxid.h"
class LLLiveLSLFile;
@ -53,6 +54,23 @@ class LLScriptEdContainer;
class LLFloaterGotoLine;
class LLFloaterExperienceProfile;
class LLLiveLSLFile : public LLLiveFile
{
public:
typedef boost::function<bool(const std::string& filename)> change_callback_t;
LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
~LLLiveLSLFile();
void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
protected:
/*virtual*/ bool loadFile();
change_callback_t mOnChangeCallback;
bool mIgnoreNextUpdate;
};
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
class LLScriptEdCore : public LLPanel
{

View File

@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
}
}
bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide)
{
if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu))
return false;
setNotHighlighted( );
bool bVisible(false);
for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
bVisible |= (*itr)->hightlightAndHide( aFilter );
if( aFilter.empty() )
{
if( mCtrl )
@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter
return true;
}
bool bHighlighted(!hide);
if( mLabel.find( aFilter ) != LLWString::npos )
{
if( mCtrl )
mCtrl->setHighlighted( true );
return true;
bHighlighted = true;
}
if( mCtrl && !bVisible )
bool bVisible(false);
for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted);
if (mCtrl && !bVisible && !bHighlighted)
{
mWasHiddenBySearch = true;
mMenu->setVisible(FALSE);
}
return bVisible;
return bVisible || bHighlighted;
}

View File

@ -107,7 +107,7 @@ namespace ll
SearchableItem();
void setNotHighlighted( );
bool hightlightAndHide( LLWString const &aFilter );
bool hightlightAndHide( LLWString const &aFilter, bool hide = true );
};
struct SearchData

View File

@ -3864,6 +3864,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
return TRUE;
}
BOOL LLSelectMgr::isSelfAvatarSelected()
{
if (mAllowSelectAvatar)
{
return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
}
return FALSE;
}
//--------------------------------------------------------------------
// Duplicate objects
@ -3886,6 +3894,17 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
make_ui_sound("UISndInvalidOp");
return;
}
if (!canDuplicate())
{
LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true);
if (node)
{
LLSD args;
args["OBJ_NAME"] = node->mName;
LLNotificationsUtil::add("NoCopyPermsNoObject", args);
return;
}
}
LLDuplicateData data;
data.offset = offset;
@ -6765,8 +6784,28 @@ void LLSelectMgr::pauseAssociatedAvatars()
mSelectedObjects->mSelectType = getSelectTypeForObject(object);
bool is_attached = false;
if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT &&
isAgentAvatarValid() && object->getParent() != NULL)
isAgentAvatarValid())
{
// Selection can be obsolete, confirm that this is an attachment
LLViewerObject* parent = (LLViewerObject*)object->getParent();
while (parent != NULL)
{
if (parent->isAvatar())
{
is_attached = true;
break;
}
else
{
parent = (LLViewerObject*)parent->getParent();
}
}
}
if (is_attached)
{
if (object->isAnimatedObject())
{
@ -6784,14 +6823,12 @@ void LLSelectMgr::pauseAssociatedAvatars()
mPauseRequests.push_back(gAgentAvatarp->requestPause());
}
}
else
else if (object && object->isAnimatedObject() && object->getControlAvatar())
{
if (object && object->isAnimatedObject() && object->getControlAvatar())
{
// Is a non-attached animated object. Pause the control avatar.
mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
// Is a non-attached animated object. Pause the control avatar.
mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
}
}

View File

@ -714,6 +714,8 @@ public:
LLPermissions* findObjectPermissions(const LLViewerObject* object);
BOOL isSelfAvatarSelected();
void selectDelete(); // Delete on simulator
void selectForceDelete(); // just delete, no into trash
void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator

View File

@ -564,6 +564,7 @@ void LLSidepanelInventory::updateVerbs()
mWearBtn->setEnabled(FALSE);
mPlayBtn->setVisible(FALSE);
mPlayBtn->setEnabled(FALSE);
mPlayBtn->setToolTip(std::string(""));
mTeleportBtn->setVisible(FALSE);
mTeleportBtn->setEnabled(FALSE);
mShopBtn->setVisible(TRUE);
@ -588,11 +589,23 @@ void LLSidepanelInventory::updateVerbs()
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_SOUND:
mPlayBtn->setVisible(TRUE);
mPlayBtn->setEnabled(TRUE);
mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip"));
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_GESTURE:
mPlayBtn->setVisible(TRUE);
mPlayBtn->setEnabled(TRUE);
mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip"));
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_ANIMATION:
mPlayBtn->setVisible(TRUE);
mPlayBtn->setEnabled(TRUE);
mShopBtn->setVisible(FALSE);
mPlayBtn->setEnabled(TRUE);
mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip"));
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_LANDMARK:
mTeleportBtn->setVisible(TRUE);

View File

@ -34,7 +34,6 @@
#include "lleconomy.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefilter.h"
@ -572,7 +571,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
if (mThumbnailSubsampled)
{
// The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
// The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
raw->resize( mPreviewImage->getWidth(),
mPreviewImage->getHeight(),
mPreviewImage->getComponents());
@ -638,7 +637,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage()
if (raw)
{
// The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
// The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
mBigThumbnailWidth = mPreviewImage->getWidth();
mBigThumbnailHeight = mPreviewImage->getHeight();
raw->resize( mBigThumbnailWidth,

View File

@ -99,7 +99,7 @@ void LLSurfacePatch::dirty()
}
else
{
LL_WARNS() << "No viewer object for this surface patch!" << LL_ENDL;
LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
}
mDirtyZStats = TRUE;

View File

@ -66,6 +66,7 @@ bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency");
@ -1311,6 +1312,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
}
else
{
@ -1326,7 +1328,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << ": Not in Cache" << LL_ENDL;
setState(LOAD_FROM_NETWORK);
}
record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
// fall through
}
}

View File

@ -312,6 +312,7 @@ public:
static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency;
static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency;
static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency;
static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate;
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only

View File

@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
{
mMouseDown = TRUE;
gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build"));
return TRUE;
}

View File

@ -111,9 +111,64 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = FALSE;
mMouseDownX = x;
mMouseDownY = y;
LLTimer pick_timer;
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged);
LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
LLViewerObject *transp_object = transparent_pick.getObject();
LLViewerObject *visible_object = visible_pick.getObject();
// Current set of priorities
// 1. Transparent attachment pick
// 2. Transparent actionable pick
// 3. Visible attachment pick (e.x we click on attachment under invisible floor)
// 4. Visible actionable pick
// 5. Transparent pick (e.x. movement on transparent object/floor, our default pick)
// left mouse down always picks transparent (but see handleMouseUp).
// Also see LLToolPie::handleHover() - priorities are a bit different there.
// Todo: we need a more consistent set of rules to work with
if (transp_object == visible_object || !visible_object)
{
// Note: if transparent object is null, then visible object is also null
// since transparent pick includes non-tranpsarent one.
// !transparent_object check will be covered by transparent_object == visible_object.
mPick = transparent_pick;
}
else
{
// Select between two non-null picks
LLViewerObject *transp_parent = transp_object->getRootEdit();
LLViewerObject *visible_parent = visible_object->getRootEdit();
if (transp_object->isAttachment())
{
// 1. Transparent attachment
mPick = transparent_pick;
}
else if (transp_object->getClickAction() != CLICK_ACTION_DISABLED
&& (useClickAction(mask, transp_object, transp_parent) || transp_object->flagHandleTouch() || (transp_parent && transp_parent->flagHandleTouch())))
{
// 2. Transparent actionable pick
mPick = transparent_pick;
}
else if (visible_object->isAttachment())
{
// 3. Visible attachment pick
mPick = visible_pick;
}
else if (visible_object->getClickAction() != CLICK_ACTION_DISABLED
&& (useClickAction(mask, visible_object, visible_parent) || visible_object->flagHandleTouch() || (visible_parent && visible_parent->flagHandleTouch())))
{
// 4. Visible actionable pick
mPick = visible_pick;
}
else
{
// 5. Default: transparent
mPick = transparent_pick;
}
}
LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
//left mouse down always picks transparent (but see handleMouseUp)
mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
mPick.mKeyMask = mask;
mMouseButtonDown = true;

View File

@ -38,8 +38,12 @@
#include "llcoros.h"
#include "reader.h"
#include "llcorehttputil.h"
#include "llurlregistry.h"
static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">");
static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>");
/**
* Handler of an HTTP machine translation service.
*
@ -99,6 +103,8 @@ public:
*/
virtual bool isConfigured() const = 0;
virtual LLTranslate::EService getCurrentService() = 0;
virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0;
virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure);
@ -248,6 +254,8 @@ public:
std::string& err_msg) const;
/*virtual*/ bool isConfigured() const;
/*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; }
/*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
private:
@ -409,6 +417,8 @@ public:
std::string& err_msg) const;
/*virtual*/ bool isConfigured() const;
/*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; }
/*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
private:
static std::string getAPIKey();
@ -520,7 +530,59 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri
{
LLTranslationAPIHandler& handler = getPreferredHandler();
handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), mesg, success, failure);
handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), addNoTranslateTags(mesg), success, failure);
}
std::string LLTranslate::addNoTranslateTags(std::string mesg)
{
if (getPreferredHandler().getCurrentService() != SERVICE_BING)
{
return mesg;
}
std::string upd_msg(mesg);
LLUrlMatch match;
S32 dif = 0;
//surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation
while (LLUrlRegistry::instance().findUrl(mesg, match))
{
upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG);
upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG);
mesg.erase(match.getStart(), match.getEnd() - match.getStart());
dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size();
}
return upd_msg;
}
std::string LLTranslate::removeNoTranslateTags(std::string mesg)
{
if (getPreferredHandler().getCurrentService() != SERVICE_BING)
{
return mesg;
}
std::string upd_msg(mesg);
LLUrlMatch match;
S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size();
S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size();
S32 dif = 0;
//remove 'no-translate' tags we added to the links before
while (LLUrlRegistry::instance().findUrl(mesg, match))
{
if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG)
{
upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size);
dif -= opening_tag_size;
if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG)
{
upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " ");
dif -= closing_tag_size - 1;
}
}
mesg.erase(match.getStart(), match.getUrl().size());
dif += match.getUrl().size();
}
return upd_msg;
}
/*static*/

View File

@ -91,6 +91,9 @@ public :
*/
static bool isTranslationConfigured();
static std::string addNoTranslateTags(std::string mesg);
static std::string removeNoTranslateTags(std::string mesg);
private:
static LLTranslationAPIHandler& getPreferredHandler();
static LLTranslationAPIHandler& getHandler(EService service);

View File

@ -28,6 +28,7 @@
#include "llviewerprecompiledheaders.h"
#include "lltwitterconnect.h"
#include "llflickrconnect.h"
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
@ -65,6 +66,49 @@ void toast_user_for_twitter_success()
LLNotificationsUtil::add("TwitterConnect", args);
}
class LLTwitterConnectHandler : public LLCommandHandler
{
public:
LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {}
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (tokens.size() >= 1)
{
if (tokens[0].asString() == "connect")
{
if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
{
// this command probably came from the twitter_web browser, so close it
LLFloaterReg::hideInstance("twitter_web");
// connect to twitter
if (query_map.has("oauth_token"))
{
LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
}
return true;
}
else if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
{
// this command probably came from the flickr_web browser, so close it
LLFloaterReg::hideInstance("flickr_web");
// connect to flickr
if (query_map.has("oauth_token"))
{
LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
}
return true;
}
}
}
return false;
}
};
LLTwitterConnectHandler gTwitterConnectHandler;
///////////////////////////////////////////////////////////////////////////////
//
void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)

View File

@ -47,6 +47,7 @@
// library includes
#include "llnotificationsutil.h"
#include "llsd.h"
#include "stringize.h"
static LLURLDispatcherListener sURLDispatcherListener;
@ -255,14 +256,23 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL&
// Teleportation links are handled here because they are tightly coupled
// to SLURL parsing and sim-fragment parsing
class LLTeleportHandler : public LLCommandHandler
class LLTeleportHandler : public LLCommandHandler, public LLEventAPI
{
public:
// Teleport requests *must* come from a trusted browser
// inside the app, otherwise a malicious web page could
// cause a constant teleport loop. JC
LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { }
LLTeleportHandler() :
LLCommandHandler("teleport", UNTRUSTED_THROTTLE),
LLEventAPI("LLTeleportHandler", "Low-level teleport API")
{
LLEventAPI::add("teleport",
"Teleport to specified [\"regionname\"] at\n"
"specified region-relative [\"x\"], [\"y\"], [\"z\"].\n"
"If [\"regionname\"] omitted, teleport to GLOBAL\n"
"coordinates [\"x\"], [\"y\"], [\"z\"].",
&LLTeleportHandler::from_event);
}
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
@ -293,6 +303,41 @@ public:
return true;
}
void from_event(const LLSD& params) const
{
Response response(LLSD(), params);
if (params.has("regionname"))
{
// region specified, coordinates (if any) are region-local
LLVector3 local_pos(
params.has("x")? params["x"].asReal() : 128,
params.has("y")? params["y"].asReal() : 128,
params.has("z")? params["z"].asReal() : 0);
std::string regionname(params["regionname"]);
std::string destination(LLSLURL(regionname, local_pos).getSLURLString());
// have to resolve region's global coordinates first
teleport_via_slapp(regionname, destination);
response["message"] = "Teleporting to " + destination;
}
else // no regionname
{
// coordinates are global, and at least (x, y) are required
if (! (params.has("x") && params.has("y")))
{
return response.error("Specify either regionname or global (x, y)");
}
LLVector3d global_pos(params["x"].asReal(), params["y"].asReal(),
params["z"].asReal());
gAgent.teleportViaLocation(global_pos);
LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
if (instance)
{
instance->trackLocation(global_pos);
}
response["message"] = STRINGIZE("Teleporting to global " << global_pos);
}
}
static void teleport_via_slapp(std::string region_name, std::string callback_url)
{

View File

@ -231,6 +231,7 @@ void display_stats()
static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD");
static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky");
static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
@ -632,7 +633,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
display_update_camera();
stop_glerror();
{
LL_RECORD_BLOCK_TIME(FTM_EEP_UPDATE);
// update all the sky/atmospheric/water settings
@ -1303,6 +1304,7 @@ void render_ui(F32 zoom_factor, int subfield)
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
render_hud_elements();
render_hud_attachments();
}

View File

@ -64,7 +64,6 @@
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
#include "llfloaterfacebook.h"
#include "llfloaterfixedenvironment.h"
#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
@ -355,11 +354,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("fbc_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("facebook", "floater_facebook.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFacebook>);
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);

View File

@ -64,7 +64,12 @@ LLViewerKeyboard gViewerKeyboard;
void agent_jump( EKeystate s )
{
if( KEYSTATE_UP == s ) return;
static BOOL first_fly_attempt(TRUE);
if (KEYSTATE_UP == s)
{
first_fly_attempt = TRUE;
return;
}
F32 time = gKeyboard->getCurKeyElapsedTime();
S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
@ -77,7 +82,8 @@ void agent_jump( EKeystate s )
}
else
{
gAgent.setFlying(TRUE);
gAgent.setFlying(TRUE, first_fly_attempt);
first_fly_attempt = FALSE;
gAgent.moveUp(1);
}
}

View File

@ -1707,7 +1707,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
// Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others)
// Do not use a spare if launching with full viewer control (e.g. Twitter and few others)
if ((plugin_basename == "media_plugin_cef") &&
!gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser)
{
@ -1901,21 +1901,8 @@ void LLViewerMediaImpl::loadURI()
// trim whitespace from front and back of URL - fixes EXT-5363
LLStringUtil::trim( mMediaURL );
// *HACK: we don't know if the URI coming in is properly escaped
// (the contract doesn't specify whether it is escaped or not.
// but LLQtWebKit expects it to be, so we do our best to encode
// special characters)
// The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt
// Note especially that '%' and '/' are there.
std::string uri = LLURI::escape(mMediaURL,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789"
"$-_.+"
"!*'(),"
"{}|\\^~[]`"
"<>#%"
";/?:@&=",
false);
// URI often comes unescaped
std::string uri = LLURI::escapePathAndData(mMediaURL);
{
// Do not log the query parts
LLURI u(uri);

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