summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/CMakeLists.txt10
-rw-r--r--indra/cmake/00-Common.cmake2
-rw-r--r--indra/llcommon/lluri.cpp98
-rw-r--r--indra/llcommon/lluri.h8
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp3
-rw-r--r--indra/llrender/llfontfreetype.cpp120
-rw-r--r--indra/llrender/llfontfreetype.h9
-rw-r--r--indra/llrender/llfontgl.cpp14
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llfontregistry.cpp107
-rw-r--r--indra/llrender/llfontregistry.h4
-rw-r--r--indra/llui/lllayoutstack.cpp1
-rw-r--r--indra/llui/llui.cpp6
-rw-r--r--indra/llwindow/llwindowwin32.cpp13
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp14
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/llagent.cpp7
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappearancemgr.cpp1
-rw-r--r--indra/newview/llappviewer.cpp18
-rw-r--r--indra/newview/llfasttimerview.cpp30
-rw-r--r--indra/newview/llfasttimerview.h4
-rw-r--r--indra/newview/llfloatertools.cpp5
-rw-r--r--indra/newview/llgroupmgr.cpp4
-rw-r--r--indra/newview/llgroupmgr.h5
-rw-r--r--indra/newview/llinventorybridge.cpp7
-rw-r--r--indra/newview/llmachineid.cpp35
-rw-r--r--indra/newview/llpanelgroupinvite.cpp19
-rw-r--r--indra/newview/llpanellogin.cpp5
-rw-r--r--indra/newview/llpanelobjectinventory.cpp11
-rw-r--r--indra/newview/llpanelobjectinventory.h6
-rw-r--r--indra/newview/llpanelplaceprofile.cpp12
-rw-r--r--indra/newview/llpreviewnotecard.cpp166
-rw-r--r--indra/newview/llpreviewnotecard.h31
-rw-r--r--indra/newview/llpreviewscript.cpp17
-rw-r--r--indra/newview/llpreviewscript.h18
-rw-r--r--indra/newview/llsearchableui.cpp19
-rw-r--r--indra/newview/llsearchableui.h2
-rw-r--r--indra/newview/llselectmgr.cpp40
-rw-r--r--indra/newview/llselectmgr.h2
-rw-r--r--indra/newview/llsidepanelinventory.cpp15
-rw-r--r--indra/newview/llsurfacepatch.cpp2
-rw-r--r--indra/newview/lltoolcomp.cpp2
-rw-r--r--indra/newview/llviewerkeyboard.cpp10
-rw-r--r--indra/newview/llviewermedia.cpp17
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewertexturelist.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp2
-rw-r--r--indra/newview/llvlcomposition.cpp11
-rw-r--r--indra/newview/llvoicevivox.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_experienceprofile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_fast_timers.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml12
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_facebook_photo.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_photo.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_postcard_message.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_profile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_photo.xml1
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml2
66 files changed, 784 insertions, 221 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 6c20a813ba..62a8f3f003 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -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
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 40fc706a99..03da30649a 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -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")
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 758b98e143..9942bc0cf8 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -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()
{
}
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 9e44cc7da2..b8fca0ca51 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -158,6 +158,14 @@ public:
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.
*
* @param str The escped URI to unescape.
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index abd304f6a5..975ce8a4d5 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -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)
{
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index ab668dc192..e9d852c288 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -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;
@@ -297,6 +257,78 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
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;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index aadebf5e70..1afe84e770 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -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;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 8cd18c5fa1..b79615e730 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -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");
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 7d0e53f60f..10891faed9 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -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,
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 3c829596ce..dbe71e2882 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -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)
{
@@ -61,6 +63,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):
mName(name),
@@ -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;
}
}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 177eb6c8a5..e30c81c630 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -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;
};
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index b1ba725c2f..955e7089f4 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -516,7 +516,6 @@ LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
{
if (!panelp) return NULL;
- e_panel_list_t::const_iterator panel_it;
BOOST_FOREACH(LLLayoutPanel* p, mPanels)
{
if (p == panelp)
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index e9f8ba020e..a1b31fd5cc 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -237,13 +237,9 @@ void LLUI::dirtyRect(LLRect rect)
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
S32 screen_x, screen_y;
-#if defined(LL_DARWIN)
- screen_x = ll_round((F32)x);
- screen_y = ll_round((F32)y);
-#else
screen_x = ll_round((F32)x * getScaleFactor().mV[VX]);
screen_y = ll_round((F32)y * getScaleFactor().mV[VY]);
-#endif
+
LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 504c1589b0..a24f168ab1 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -738,6 +738,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()
@@ -811,7 +822,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"),
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 66b316df90..559cfc0b7a 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -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,
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 766dc5226c..2c52b400e4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1881,12 +1881,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(
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index ba250fa471..4bd3ca9157 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -742,7 +742,7 @@ BOOL LLAgent::getFlying() const
//-----------------------------------------------------------------------------
// setFlying()
//-----------------------------------------------------------------------------
-void LLAgent::setFlying(BOOL fly)
+void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
{
if (isAgentAvatarValid())
{
@@ -771,7 +771,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
- make_ui_sound("UISndBadKeystroke");
+ if (fail_sound)
+ {
+ make_ui_sound("UISndBadKeystroke");
+ }
return;
}
if( !was_flying )
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index b1b39b637e..ea6f68c482 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -337,7 +337,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?
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 08daeb0f59..22bcbad7da 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1865,7 +1865,6 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)
LLFindNonRemovableObjects filter_non_removable;
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
- LLInventoryModel::item_array_t::const_iterator it;
gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable);
if (!cats.empty() || !items.empty())
{
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 577082f01f..6202a382b1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1167,11 +1167,14 @@ bool LLAppViewer::init()
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
+#if !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS
+ // This is neither a release package, nor crash-reporting enabled test build
+ // Note: pointless to launch on Windows - it shouldn't expect secondlife-bin.exe
+ LL_WARNS("LLLeap") << "Launching without version checker" << LL_ENDL;
+#else
// Run the updater. An exception from launching the updater should bother us.
- if (!beingDebugged())
- {
- LLLeap::create(updater, true);
- }
+ LLLeap::create(updater, true);
+#endif
// Iterate over --leap command-line options. But this is a bit tricky: if
// there's only one, it won't be an array at all.
@@ -3173,6 +3176,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();
@@ -3315,6 +3322,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"))
{
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index f68e63cb96..98687282ed 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -43,6 +43,7 @@
#include "llsdserialize.h"
#include "lltooltip.h"
#include "llbutton.h"
+#include "llscrollbar.h"
#include "llappviewer.h"
#include "llviewertexturelist.h"
@@ -128,7 +129,8 @@ 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)
@@ -1197,6 +1199,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 +1207,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 +1298,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());
}
}
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 3e30bd86ba..ff65f8da07 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -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
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index ee4fdbe9a5..c2c15ee12b 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -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);
}
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 152d0eddcd..088d052533 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -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",
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 940ef6eea1..cf9735e38a 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -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; }
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 00b7732ee9..e13f8343a0 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2101,7 +2101,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;
@@ -7358,8 +7360,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
LLViewerInventoryItem* item = gInventory.getItem(*it);
- LLAssetType::EType asset_type = item->getType();
- if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE))
+ if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
{
return false;
}
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index b0ee8e7fcb..2001359e50 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -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
@@ -218,16 +218,19 @@ S32 LLMachineID::init()
// Get the value of the Name property
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
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)
{
for (unsigned int i = 0; i < len; i++)
{
- if (vtProp.bstrVal[j] == 0)
+ if (j >= serial_size)
break;
-
+
static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
j++;
}
@@ -254,16 +257,8 @@ S32 LLMachineID::init()
ret_code = LLUUID::getNodeID(staticPtr);
#endif
has_static_unique_id = true;
- return ret_code;
-}
-
-S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
-{
- if (has_static_unique_id)
- {
- memcpy ( unique_id, &static_unique_id, len);
- LL_INFOS_ONCE("AppInit") << "UniqueID: 0x";
+ 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)
@@ -271,11 +266,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
// 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];
+ 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;
+}
+
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+ if (has_static_unique_id)
+ {
+ memcpy ( unique_id, &static_unique_id, len);
return 1;
}
return 0;
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 82ea8377de..d6b66ee622 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -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
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 142dea83e2..0637010b0b 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -748,7 +748,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;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index cd1875e995..5aa80651c4 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1498,7 +1498,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
{
@@ -1768,7 +1775,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)
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index d700c8f4cf..7b9ecfb8f3 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -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;
};
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 610b3a6396..104316e253 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -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())
{
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index d4a8bbdf45..f012d99adf 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -32,6 +32,7 @@
#include "llagent.h"
#include "lldraghandle.h"
+#include "llexternaleditor.h"
#include "llviewerwindow.h"
#include "llbutton.h"
#include "llfloaterreg.h"
@@ -63,7 +64,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 +76,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 +91,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);
@@ -408,6 +413,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;
@@ -468,7 +483,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");
@@ -487,7 +502,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
}
editor->makePristine();
-
+ if (sync)
+ {
+ syncExternal();
+ }
const LLInventoryItem* item = getItem();
// save it out to database
if (item)
@@ -566,6 +584,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));
@@ -714,4 +744,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 = getString("external_editor_not_set");
+ }
+ 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
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 46a6d0ef50..d9c14815c1 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -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;
};
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 9431914ba3..76a21077ba 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -41,7 +41,6 @@
#include "llinventorymodel.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
-#include "lllivefile.h"
#include "llhelp.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
@@ -120,22 +119,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)
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 69cf9d9158..74e4c00d43 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -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
{
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index de90896548..93143eb33f 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -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;
}
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 42b2866fb6..9741557e49 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -107,7 +107,7 @@ namespace ll
SearchableItem();
void setNotHighlighted( );
- bool hightlightAndHide( LLWString const &aFilter );
+ bool hightlightAndHide( LLWString const &aFilter, bool hide = true );
};
struct SearchData
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index b36df244f8..97c547e524 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -3861,6 +3861,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
return TRUE;
}
+BOOL LLSelectMgr::isSelfAvatarSelected()
+{
+ if (mAllowSelectAvatar)
+ {
+ return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+ }
+ return FALSE;
+}
//--------------------------------------------------------------------
// Duplicate objects
@@ -6686,8 +6694,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())
{
@@ -6705,14 +6733,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());
}
+
}
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0fee8803..3e8bfdb00e 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -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
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 689734e36a..ea7e649792 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -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);
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index d28a7cc048..f6cf714db4 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -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;
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 392c103d7c..f9c327b46e 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -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;
}
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index b89e1497a1..e930eb20d3 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -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);
}
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d8745b1eca..9f02c4b17c 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -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);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ba68ce4cf4..aa6d75f5fb 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4066,10 +4066,8 @@ void near_sit_down_point(BOOL success, void *)
if (success)
{
gAgent.setFlying(FALSE);
+ gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
-
- // Might be first sit
- //LLFirstUse::useSit();
}
}
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 4308405c64..06524847d1 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -512,7 +512,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM)
{
// Workaround: we need BOOST_ALM texture for something, 'rise' to NONE
- imagep->setDecodePriority(LLViewerTexture::BOOST_NONE);
+ imagep->setBoostLevel(LLViewerTexture::BOOST_NONE);
}
LLViewerFetchedTexture *texture = imagep.get();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 5b764f97fb..6d351f0639 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3819,7 +3819,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
BOOL draw_handles = TRUE;
- if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move)
+ if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
{
draw_handles = FALSE;
}
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c4430f4308..c63c5f6b23 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -99,6 +99,8 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id)
{
return;
}
+ // This is terrain texture, but we are not setting it as BOOST_TERRAIN
+ // since we will be manipulating it later as needed.
mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
mDetailTextures[corner]->setNoDelete() ;
mRawImages[corner] = NULL;
@@ -241,6 +243,7 @@ BOOL LLVLComposition::generateComposition()
}
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->setMinDiscardLevel(ddiscard);
+ mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
return FALSE;
}
}
@@ -287,7 +290,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
{
mDetailTextures[i]->destroyRawImage() ;
}
- LL_DEBUGS() << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << LL_ENDL;
+ LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL;
return FALSE;
}
@@ -323,12 +326,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
if (x_end > mWidth)
{
- LL_WARNS() << "x end > width" << LL_ENDL;
+ LL_WARNS("Terrain") << "x end > width" << LL_ENDL;
x_end = mWidth;
}
if (y_end > mWidth)
{
- LL_WARNS() << "y end > width" << LL_ENDL;
+ LL_WARNS("Terrain") << "y end > width" << LL_ENDL;
y_end = mWidth;
}
@@ -358,7 +361,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
if (tex_comps != st_comps)
{
- LL_WARNS() << "Base texture comps != input texture comps" << LL_ENDL;
+ LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL;
return FALSE;
}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index cf40058c34..2231bda33e 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -770,12 +770,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
{
#ifndef VIVOXDAEMON_REMOTEHOST
// Launch the voice daemon
- std::string exe_path = gDirUtilp->getAppRODataDir();
#if LL_WINDOWS
+ // On windows use exe (not work or RO) directory
+ std::string exe_path = gDirUtilp->getExecutableDir();
gDirUtilp->append(exe_path, "SLVoice.exe");
#elif LL_DARWIN
+ // On MAC use resource directory
+ std::string exe_path = gDirUtilp->getAppRODataDir();
gDirUtilp->append(exe_path, "SLVoice");
#else
+ std::string exe_path = gDirUtilp->getExecutableDir();
gDirUtilp->append(exe_path, "SLVoice");
#endif
// See if the vivox executable exists
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index d04e738b22..51f455b1e3 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -163,6 +163,7 @@
layout="topleft"
left_pad="2"
name="Description"
+ spellcheck="true"
top_delta="0"
width="365"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
index 2dfba1ac44..f275fec066 100644
--- a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
+++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
@@ -493,6 +493,7 @@
layout="topleft"
left="11"
name="edit_experience_description"
+ spellcheck="true"
max_length="2048"
text_color="black"
right="-11"
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index fa7147d9ca..645003cc14 100644
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -60,10 +60,21 @@
min_width="100">
<panel top="0"
left="0"
- width="220"
+ width="204"
height="440"
name="legend"
follows="all"/>
+ <scroll_bar
+ top ="0"
+ right="-1"
+ height="440"
+ width="15"
+ follows="top|right|bottom"
+ name="scroll_vert"
+ orientation="vertical"
+ step_size="16"
+ doc_size="3000"
+ />
</layout_panel>
<layout_panel name="timers_panel"
auto_resize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 200e9b9537..9f051d9f8d 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -119,6 +119,7 @@
follows="left|bottom"
height="23"
label="Edit"
+ tool_tip="Open window for editing selected gesture."
layout="topleft"
left="6"
name="edit_btn"
@@ -128,6 +129,7 @@
follows="left|bottom"
height="23"
label="Play"
+ tool_tip="Execute selected gesture in-world."
layout="topleft"
left_pad="6"
name="play_btn"
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 2e1c8ce670..dcbdfa8794 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -6,7 +6,7 @@
height="361"
layout="topleft"
min_height="243"
- min_width="234"
+ min_width="330"
name="preview notecard"
help_topic="preview_notecard"
title="NOTECARD:"
@@ -77,6 +77,16 @@
word_wrap="true">
Loading...
</text_editor>
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Edit..."
+ label_selected="Edit"
+ layout="topleft"
+ left="4"
+ name="Edit"
+ top="332"
+ width="100" />
<button
follows="right|bottom"
height="22"
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 8b1d50e58f..87c39b1024 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -10,6 +10,7 @@
<file>simhei.ttf</file>
<file>ArialUni.ttf</file>
<file>msyh.ttc</file>
+ <file load_collection="true">Cambria.ttc</file>
</os>
<os name="Mac">
<file>ヒラギノ角ゴシック W3.ttc</file>
@@ -21,6 +22,7 @@
<file>AppleSDGothicNeo-Regular.otf</file>
<file>华文细黑.ttf</file>
<file>PingFang.ttc</file>
+ <file>STIXGeneral.otf</file>
</os>
</font>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
index 22e6598352..97355f4689 100644
--- a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
@@ -138,6 +138,7 @@
length="1"
max_length="700"
name="photo_caption"
+ spellcheck="true"
type="string"
word_wrap="true">
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
index 6074ab9ef6..7fb2291423 100644
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -158,6 +158,7 @@
length="1"
max_length="700"
name="photo_description"
+ spellcheck="true"
type="string"
word_wrap="true">
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 26f54bacbc..e34335a2af 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -214,7 +214,7 @@ Hover your mouse over the options for more help.
layout="topleft"
left="10"
name="group_mature_check"
- tool_tip="Sets whether your group contains information rated as Moderate"
+ tool_tip="Maturity ratings designate the type of content and behavior allowed in a group"
top_pad="4"
width="190">
<combo_item name="select_mature" value="Select">
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index fd6e96b9a7..13986c4030 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -277,6 +277,7 @@
max_length="127"
name="notes_editor"
read_only="true"
+ spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
top_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
index 331a08b4bb..63c7259878 100644
--- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
@@ -80,6 +80,7 @@
left="5"
max_length="700"
name="msg_form"
+ spellcheck="true"
right="-4"
top_pad="5"
word_wrap="true">
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 5d060c0a0d..8243c2715d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -94,6 +94,7 @@
layout="topleft"
left_delta="0"
name="texture_detail_0"
+ default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5"
top_delta="20"
width="100" />
<texture_picker
@@ -102,6 +103,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_1"
+ default_image_id="63338ede-0037-c4fd-855b-015d77112fc8"
top_delta="0"
width="100" />
<texture_picker
@@ -110,6 +112,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_2"
+ default_image_id="303cd381-8560-7579-23f1-f0a880799740"
top_delta="0"
width="100" />
<texture_picker
@@ -118,6 +121,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_3"
+ default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c"
top_delta="0"
width="100" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index d86cb92981..2fdbee49f0 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
@@ -126,6 +126,7 @@
length="1"
max_length="700"
name="caption"
+ spellcheck="true"
width="200"
top_pad="2"
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
index 9a460ceead..8774d09a03 100644
--- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
@@ -39,6 +39,7 @@
length="1"
max_length="140"
name="photo_status"
+ spellcheck="true"
type="string"
word_wrap="true">
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 4dbafd27e0..e567e410bc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -58,6 +58,9 @@ Advanced Lighting Model: [GPU_SHADERS]
Texture memory: [TEXTURE_MEMORY]MB
VFS (cache) creation time: [VFS_TIME]
</string>
+ <string name="AboutOSXHiDPI">
+HiDPI display mode: [HIDPI]
+ </string>
<string name="AboutLibs">
J2C Decoder Version: [J2C_VERSION]
Audio Driver Version: [AUDIO_DRIVER_VERSION]
@@ -2299,6 +2302,9 @@ For AI Character: Get the closest navigable point to the point provided.
<string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string>
<string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string>
<string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string>
+ <string name="InventoryPlayAnimationTooltip">Open window with Play options.</string>
+ <string name="InventoryPlayGestureTooltip">Execute selected gesture in-world.</string>
+ <string name="InventoryPlaySoundTooltip">Open window with Play options.</string>
<string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string>
<string name="InventoryOutboxNotMerchantTooltip"></string>
<string name="InventoryOutboxNotMerchant">
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 3ac2cfb69b..4239c949fd 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2987,7 +2987,7 @@ Si vous restez dans cette région, vous serez déconnecté(e).
Si vous restez dans cette région, vous serez déconnecté(e).
</notification>
<notification name="LoadWebPage">
- Charger la page Web [URL] ?
+Charger la page Web [URL] ?
[MESSAGE]