diff options
Diffstat (limited to 'indra')
60 files changed, 747 insertions, 209 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 a7e8db1b1c..88e8bb49b4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1879,12 +1879,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/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 610b3a6396..13e50904c2 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"), parcel->getSalePrice())); +		mAreaText->setText(llformat("%d %s", area, getString("area_text")));  		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"), parcel->getPrimCount(), getString("allocated")));  		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/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/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..58f8acb0d1 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;  		}  	} 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 535af317d9..58adac4e73 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -151,6 +151,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_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 d91f3ac095..823109e55f 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] diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 18b3b2a35e..861090772e 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2963,7 +2963,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] | 
