diff options
42 files changed, 309 insertions, 277 deletions
| diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index 0ba62fb698..41fbb97175 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -70,7 +70,6 @@ LLDir *gDirUtilp = (LLDir *)&gDirUtil;  /// Values for findSkinnedFilenames(subdir) parameter  const char  	*LLDir::XUI      = "xui", -	*LLDir::HTML     = "html",  	*LLDir::TEXTURES = "textures",  	*LLDir::SKINBASE = ""; @@ -761,13 +760,14 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,  		else  		{  			// We do not recognize this subdir. Investigate. -			if (skinExists(subdir, "en")) +			std::string subdir_path(add(getDefaultSkinDir(), subdir)); +			if (fileExists(add(subdir_path, "en")))  			{  				// defaultSkinDir/subdir contains subdir "en". That's our  				// default language; this subdir is localized.  				found = sLocalized.insert(StringMap::value_type(subdir, "en")).first;  			} -			else if (skinExists(subdir, "en-us")) +			else if (fileExists(add(subdir_path, "en-us")))  			{  				// defaultSkinDir/subdir contains subdir "en-us" but not "en".  				// Set as default language; this subdir is localized. @@ -864,33 +864,6 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,  	return results;  } -// virtual -bool LLDir::skinExists(const std::string& subdir, const std::string& skin) const -{ -    std::string skin_path(add(getDefaultSkinDir(), subdir, skin)); -    return fileExists(skin_path); -} - -// virtual -std::string LLDir::getFileContents(const std::string& filename) const -{ -    LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ -    if (fp) -    { -        fseek(fp, 0, SEEK_END); -        U32 length = ftell(fp); -        fseek(fp, 0, SEEK_SET); - -        std::vector<char> buffer(length); -        size_t nread = fread(buffer.data(), 1, length, fp); -        fclose(fp); - -        return std::string(buffer.data(), nread); -    } - -    return LLStringUtil::null; -} -  std::string LLDir::getTempFilename() const  {  	LLUUID random_uuid; diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h index d43921c292..b9a046ba33 100644 --- a/indra/llfilesystem/lldir.h +++ b/indra/llfilesystem/lldir.h @@ -72,8 +72,6 @@ class LLDir  // pure virtual functions  	virtual std::string getCurPath() = 0;  	virtual bool fileExists(const std::string &filename) const = 0; -	virtual bool skinExists(const std::string& subdir, const std::string &skin) const; -	virtual std::string getFileContents(const std::string& filename) const;  	const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;   	const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const; @@ -152,7 +150,7 @@ class LLDir  												  const std::string& filename,  												  ESkinConstraint constraint=CURRENT_SKIN) const;  	/// Values for findSkinnedFilenames(subdir) parameter -	static const char *XUI, *HTML, *TEXTURES, *SKINBASE; +	static const char *XUI, *TEXTURES, *SKINBASE;  	/**  	 * Return the base-language pathname from findSkinnedFilenames(), or  	 * the empty string if no such file exists. Parameters are identical to diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 905292a44f..c208e538fc 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,7 +50,7 @@ std::string model_names[] =  const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); -LLModel::LLModel(LLVolumeParams& params, F32 detail) +LLModel::LLModel(const LLVolumeParams& params, F32 detail)  	: LLVolume(params, detail),         mNormalizedScale(1,1,1),        mNormalizedTranslation(0, 0, 0), diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index bcd33ba2db..37e76c895c 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -150,7 +150,7 @@ public:  		LLModel::PhysicsMesh mPhysicsShapeMesh;  	}; -	LLModel(LLVolumeParams& params, F32 detail); +	LLModel(const LLVolumeParams& params, F32 detail);  	~LLModel();  	bool loadModel(std::istream& is); @@ -375,7 +375,7 @@ public:  	LLMatrix4 mTransform;  	material_map mMaterial; -	LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials) +	LLModelInstanceBase(LLModel* model, const LLMatrix4& transform, const material_map& materials)  		: mModel(model), mTransform(transform), mMaterial(materials)  	{  	} @@ -404,7 +404,7 @@ public:  	LLUUID mMeshID;  	S32 mLocalMeshID; -	LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials) +	LLModelInstance(LLModel* model, const std::string& label, const LLMatrix4& transform, const material_map& materials)  		: LLModelInstanceBase(model, transform, materials), mLabel(label)  	{  		mLocalMeshID = -1; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 25006abf2c..48693c6267 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -3522,16 +3522,12 @@ bool LLFloater::isVisible(const LLFloater* floater)      return floater && floater->getVisible();  } -bool LLFloater::buildFromFile(const std::string& filename, bool cacheable) +bool LLFloater::buildFromFile(const std::string& filename)  {      LL_PROFILE_ZONE_SCOPED; - -    llassert_msg(!cacheable || !mSingleInstance || !mReuseInstance, -        "No needs to cache XML for floater with mSingleInstance AND mReuseInstance flags set"); -  	LLXMLNodePtr root; -	if (!LLUICtrlFactory::getLayeredXMLNode(filename, root, LLDir::CURRENT_SKIN, cacheable)) +	if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))  	{  		LL_WARNS() << "Couldn't find (or parse) floater from: " << filename << LL_ENDL;  		return false; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 13d9bf5adc..f7e121ed7e 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -208,7 +208,7 @@ public:  	// Don't export top/left for rect, only height/width  	static void setupParamsForExport(Params& p, LLView* parent); -	bool buildFromFile(const std::string &filename, bool cacheable = false); +	bool buildFromFile(const std::string &filename);  	boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );  	boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb ); diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 85aa766918..5374b7ea73 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -95,7 +95,7 @@ void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition posit  	}  	llassert(LLMenuGL::sMenuContainer != NULL); -	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance(), true); +	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  	if (!menu)  	{  		LL_WARNS() << "Error loading menu_button menu" << LL_ENDL; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index bba10bd792..ba6a31eb9e 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -803,13 +803,13 @@ boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t::  //-----------------------------------------------------------------------------  // buildPanel()  //----------------------------------------------------------------------------- -bool LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params, bool cacheable) +bool LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params)  {      LL_PROFILE_ZONE_SCOPED;  	bool didPost = false;  	LLXMLNodePtr root; -	if (!LLUICtrlFactory::getLayeredXMLNode(filename, root, LLDir::CURRENT_SKIN, cacheable)) +	if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))  	{  		LL_WARNS() << "Couldn't parse panel from: " << filename << LL_ENDL;  		return didPost; diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index dd73a41132..33883bf6a4 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -107,8 +107,7 @@ protected:  public:  	typedef std::vector<class LLUICtrl *>				ctrl_list_t; -	bool buildFromFile(const std::string &filename, const LLPanel::Params& default_params, bool cacheable = false); -	bool buildFromFile(const std::string &filename, bool cacheable = false) { return buildFromFile(filename, getDefaultParams(), cacheable); } +	bool buildFromFile(const std::string &filename, const LLPanel::Params& default_params = getDefaultParams());  	static LLPanel* createFactoryPanel(const std::string& name); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 706140fd49..dca777cc1f 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -157,7 +157,7 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid  // getLayeredXMLNode()  //-----------------------------------------------------------------------------  bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, -                                        LLDir::ESkinConstraint constraint, bool cacheable) +                                        LLDir::ESkinConstraint constraint)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;  	std::vector<std::string> paths = @@ -169,7 +169,7 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo  		paths.push_back(xui_filename);  	} -	return LLXMLNode::getLayeredXMLNode(root, paths, cacheable); +	return LLXMLNode::getLayeredXMLNode(root, paths);  } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 2e1cc75508..6e585abfc0 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -148,7 +148,7 @@ public:  	LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node );  	template<typename T> -	static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, bool cacheable = false) +	static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry)  	{  		T* widget = NULL; @@ -156,7 +156,7 @@ public:  		{  			LLXMLNodePtr root_node; -			if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node, LLDir::CURRENT_SKIN, cacheable)) +			if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node))  			{                  LL_WARNS() << "Couldn't parse XUI from path: " << instance().getCurFileName() << ", from filename: " << filename << LL_ENDL;  				goto fail; @@ -192,7 +192,7 @@ fail:  	static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);  	static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root, -								  LLDir::ESkinConstraint constraint = LLDir::CURRENT_SKIN, bool cacheable = false); +								  LLDir::ESkinConstraint constraint=LLDir::CURRENT_SKIN);  private:  	//NOTE: both friend declarations are necessary to keep both gcc and msvc happy diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 6209058875..f8d4a61721 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -28,7 +28,6 @@  #include "llxuiparser.h" -#include "lldir.h"  #include "llxmlnode.h"  #include "llfasttimer.h"  #ifdef LL_USESYSTEMLIBS @@ -45,7 +44,6 @@  #include "lluicolor.h"  #include "v3math.h" -  using namespace BOOST_SPIRIT_CLASSIC_NS;  const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; @@ -1399,17 +1397,36 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl  	mCurReadDepth = 0;  	setParseSilently(silent); -	std::string xml = gDirUtilp->getFileContents(filename); -	if (xml.empty()) +	ScopedFile file(filename, "rb"); +	if( !file.isOpen() )  	{  		LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;  		XML_ParserFree( mParser );  		return false;  	} +	S32 bytes_read = 0; +	 +	S32 buffer_size = file.getRemainingBytes(); +	void* buffer = XML_GetBuffer(mParser, buffer_size); +	if( !buffer )  +	{ +		LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL; +		XML_ParserFree( mParser ); +		return false; +	} + +	bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile); +	if( bytes_read <= 0 ) +	{ +		LL_WARNS("ReadXUI") << "Error while reading file  " << filename << LL_ENDL; +		XML_ParserFree( mParser ); +		return false; +	} +	  	mEmptyLeafNode.push_back(false); -	if (!XML_Parse(mParser, xml.data(), (int)xml.size(), true)) +	if( !XML_ParseBuffer(mParser, bytes_read, true ) )  	{  		LL_WARNS("ReadXUI") << "Error while parsing file  " << filename << LL_ENDL;  		XML_ParserFree( mParser ); diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 952ad3e8cd..c0f27e2c22 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -753,13 +753,13 @@ void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val)  //---------------------------------------------------------------  // Returns number of controls loaded, so 0 if failure -U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, const std::string& xml, bool require_declaration, eControlType declare_as) +U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as)  {  	std::string name;  	LLXmlTree xml_controls; -	if (!xml_controls.parseString(xml)) +	if (!xml_controls.parseFile(filename))  	{  		LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL;  		return 0; @@ -772,7 +772,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, const std::s  		return 0;  	} -	U32 validitems = 0; +	U32		validitems = 0;  	S32 version;  	rootp->getAttributeS32("version", version); @@ -990,24 +990,24 @@ U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only  U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)  {  	LLSD settings; - -	std::string xml = gDirUtilp->getFileContents(filename); -	if (xml.empty()) +	llifstream infile; +	infile.open(filename.c_str()); +	if(!infile.is_open())  	{  		LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL;  		return 0;  	} -	std::stringstream stream(xml); -	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, stream)) +	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))  	{ +		infile.close();  		LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL; -		return loadFromFileLegacy(filename, xml, true, TYPE_STRING); +		return loadFromFileLegacy(filename, true, TYPE_STRING);  	}  	U32	validitems = 0;  	bool hidefromsettingseditor = false; - +	  	for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)  	{  		LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT; @@ -1019,7 +1019,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  			persist = control_map["Persist"].asInteger()?  					  LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO;  		} - +		  		// Sometimes we want to use the settings system to provide cheap persistence, but we  		// don't want the settings themselves to be easily manipulated in the UI because   		// doing so can cause support problems. So we have this option: @@ -1031,7 +1031,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  		{  			hidefromsettingseditor = false;  		} - +		  		// If the control exists just set the value from the input file.  		LLControlVariable* existing_control = getControl(name);  		if(existing_control) diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index e148b74292..a8bc584c48 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -300,7 +300,7 @@ public:  	// Returns number of controls loaded, 0 if failed  	// If require_declaration is false, will auto-declare controls it finds  	// as the given type. -	U32	loadFromFileLegacy(const std::string& filename, const std::string& xml, bool require_declaration = true, eControlType declare_as = TYPE_STRING); +	U32	loadFromFileLegacy(const std::string& filename, bool require_declaration = true, eControlType declare_as = TYPE_STRING);   	U32 saveToFile(const std::string& filename, bool nondefault_only);   	U32	loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);  	void	resetToDefaults(); diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index dc60b1aa66..9c7ac66f01 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -137,19 +137,19 @@ LLXMLNode::LLXMLNode(const LLXMLNode& rhs) :  }  // returns a new copy of this node and all its children -LLXMLNodePtr LLXMLNode::deepCopy() const +LLXMLNodePtr LLXMLNode::deepCopy()  {  	LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this));  	if (mChildren.notNull())  	{ -		for (LLXMLChildList::const_iterator iter = mChildren->map.begin(); +		for (LLXMLChildList::iterator iter = mChildren->map.begin();  			 iter != mChildren->map.end(); ++iter)	  		{  			LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());  			newnode->addChild(temp_ptr_for_gcc);  		}  	} -	for (LLXMLAttribList::const_iterator iter = mAttributes.begin(); +	for (LLXMLAttribList::iterator iter = mAttributes.begin();  		 iter != mAttributes.end(); ++iter)  	{  		LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); @@ -650,82 +650,37 @@ bool LLXMLNode::updateNode(  	return true;  } -static std::map<std::string, LLXMLNodePtr> sXMLCache; -static LLSharedMutex sXMLCacheMutex; - -static void saveToCache(const std::string& filename, const LLXMLNodePtr& node) -{ -    LLXMLNodePtr node_copy = node->deepCopy(); - -    LLExclusiveMutexLock lock(&sXMLCacheMutex); -    sXMLCache.emplace(filename, node_copy); -} - -static bool loadFromCache(const std::string& filename, LLXMLNodePtr& node) +// static +bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)  { -    LLSharedMutexLock lock(&sXMLCacheMutex); -    auto it = sXMLCache.find(filename); -    if (it == sXMLCache.end()) -        return false; -    node = it->second->deepCopy(); -    return true; -} +	// Read file +	LL_DEBUGS("XMLNode") << "parsing XML file: " << filename << LL_ENDL; +	LLFILE* fp = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */ +	if (fp == NULL) +	{ +		node = NULL ; +		return false; +	} +	fseek(fp, 0, SEEK_END); +	U32 length = ftell(fp); +	fseek(fp, 0, SEEK_SET); -// static -bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree, bool cacheable) -{ -    // Try to read from cache -    if (cacheable) -    { -        if (loadFromCache(filename, node)) -        { -            node->setDefault(defaults_tree); -            node->updateDefault(); -            return true; -        } -    } - -    std::string xml = gDirUtilp->getFileContents(filename); -    if (xml.empty()) -    { -        LL_WARNS("XMLNode") << "no XML file: " << filename << LL_ENDL; -    } -    else if (parseBuffer(xml.data(), xml.size(), node)) -    { -        if (cacheable) -        { -            saveToCache(filename, node); -        } -        node->setDefault(defaults_tree); -        node->updateDefault(); -        return true; -    } - -    node = nullptr; -    return false; -} +	U8* buffer = new U8[length+1]; +	size_t nread = fread(buffer, 1, length, fp); +	buffer[nread] = 0; +	fclose(fp); -// static -bool LLXMLNode::parseBuffer( -    const char* buffer, -    U32 length, -    LLXMLNodePtr& node, -    LLXMLNode* defaults) -{ -    if (parseBuffer(buffer, length, node)) -    { -        node->setDefault(defaults); -        node->updateDefault(); -        return true; -    } -    return false; +	bool rv = parseBuffer(buffer, nread, node, defaults_tree); +	delete [] buffer; +	return rv;  }  // static  bool LLXMLNode::parseBuffer( -	const char* buffer, +	U8* buffer,  	U32 length, -	LLXMLNodePtr& node) +	LLXMLNodePtr& node,  +	LLXMLNode* defaults)  {  	// Init  	XML_Parser my_parser = XML_ParserCreate(NULL); @@ -741,7 +696,7 @@ bool LLXMLNode::parseBuffer(  	XML_SetUserData(my_parser, (void *)file_node_ptr);  	// Do the parsing -	if (XML_Parse(my_parser, buffer, length, true) != XML_STATUS_OK) +	if (XML_Parse(my_parser, (const char *)buffer, length, true) != XML_STATUS_OK)  	{  		LL_WARNS() << "Error parsing xml error code: "  				<< XML_ErrorString(XML_GetErrorCode(my_parser)) @@ -762,6 +717,9 @@ bool LLXMLNode::parseBuffer(  	LLXMLNode *return_node = file_node->mChildren->map.begin()->second; +	return_node->setDefault(defaults); +	return_node->updateDefault(); +  	node = return_node;  	return true;  } @@ -866,20 +824,18 @@ bool LLXMLNode::isFullyDefault()  }  // static -bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths, bool cacheable) +bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, +								  const std::vector<std::string>& paths)  { -	if (paths.empty()) -	{ -		return false; -	} +	if (paths.empty()) return false;  	std::string filename = paths.front();  	if (filename.empty())  	{  		return false;  	} - -	if (!LLXMLNode::parseFile(filename, root, nullptr, cacheable)) +	 +	if (!LLXMLNode::parseFile(filename, root, NULL))  	{  		LL_WARNS() << "Problem reading UI description file: " << filename << LL_ENDL;  		return false; diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index e09c89c543..d5b8b36d86 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -121,39 +121,39 @@ public:  	LLXMLNode(const char* name, bool is_attribute);  	LLXMLNode(LLStringTableEntry* name, bool is_attribute);  	LLXMLNode(const LLXMLNode& rhs); -	LLXMLNodePtr deepCopy() const; +	LLXMLNodePtr deepCopy();  	bool isNull();  	bool deleteChild(LLXMLNode* child); -    void addChild(LLXMLNodePtr& new_child); +    void addChild(LLXMLNodePtr& new_child);       void setParent(LLXMLNodePtr& new_parent); // reparent if necessary -    // Deserialization +    // Serialization  	static bool parseFile(  		const std::string& filename, -		LLXMLNodePtr& node, -		LLXMLNode* defaults_tree, -		bool cacheable = false); -    static bool parseBuffer( -        const char* buffer, -        U32 length, -        LLXMLNodePtr& node, -        LLXMLNode* defaults); +		LLXMLNodePtr& node,  +		LLXMLNode* defaults_tree); +	static bool parseBuffer( +		U8* buffer, +		U32 length, +		LLXMLNodePtr& node,  +		LLXMLNode* defaults);  	static bool parseStream(  		std::istream& str, -		LLXMLNodePtr& node, +		LLXMLNodePtr& node,   		LLXMLNode* defaults);  	static bool updateNode(  		LLXMLNodePtr& node,  		LLXMLNodePtr& update_node); - -	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths, bool cacheable = false); - +	 +	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths); +	 +	  	// Write standard XML file header:  	// <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  	static void writeHeaderToFile(LLFILE *out_file); - +	  	// Write XML to file with one attribute per line.  	// XML escapes values as they are written.      void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true); @@ -237,7 +237,7 @@ public:  	// Setters  	bool setAttributeString(const char* attr, const std::string& value); - +	  	void setBoolValue(const bool value)	{ setBoolValue(1, &value); }  	void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); }  	void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); } @@ -290,10 +290,6 @@ public:  protected:  	bool removeChild(LLXMLNode* child); -    static bool parseBuffer( -        const char* buffer, -        U32 length, -        LLXMLNodePtr& node);  public:  	std::string mID;				// The ID attribute of this node diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 0c1615f486..a9c702f552 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -35,7 +35,6 @@  #include "v4math.h"  #include "llquaternion.h"  #include "lluuid.h" -#include "lldir.h"  //////////////////////////////////////////////////////////////  // LLXmlTree @@ -61,37 +60,20 @@ void LLXmlTree::cleanup()  	mNodeNames.cleanup();  } -bool LLXmlTree::parseFile(const std::string & filename, bool keep_contents) -{ -	delete mRoot; -	mRoot = NULL; - -	std::string xml = gDirUtilp->getFileContents(filename); -	if (xml.empty()) -	{ -		LL_WARNS() << "LLXmlTree parse failed. No XML file: " << filename << LL_ENDL; -		return false; -	} - -	bool success = parseString(xml, keep_contents); -	return success; -} - -bool LLXmlTree::parseString(const std::string &xml, bool keep_contents) +bool LLXmlTree::parseFile(const std::string &path, bool keep_contents)  {  	delete mRoot;  	mRoot = NULL;  	LLXmlTreeParser parser(this); -	bool success = parser.parseString(xml, &mRoot, keep_contents); -	if (!success) +	bool success = parser.parseFile( path, &mRoot, keep_contents ); +	if( !success )  	{  		S32 line_number = parser.getCurrentLineNumber();  		const char* error =  parser.getErrorString();  		LL_WARNS() << "LLXmlTree parse failed.  Line " << line_number << ": " << error << LL_ENDL;  	} -  	return success;  } @@ -554,27 +536,6 @@ bool LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, b  	return success;  } -bool LLXmlTreeParser::parseString(const std::string& xml, LLXmlTreeNode** root, bool keep_contents) -{ -	llassert( !mRoot ); -	llassert( !mCurrent ); - -	mKeepContents = keep_contents; - -	bool success = LLXmlParser::parse(xml.data(), (int)xml.size(), true); - -	*root = mRoot; -	mRoot = NULL; - -	if (success) -	{ -		llassert(!mCurrent); -	} - -	mCurrent = NULL; -	 -	return success; -}  const std::string& LLXmlTreeParser::tabs()  { diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index d47f26f731..5d15c4c7f5 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -56,7 +56,6 @@ public:  	void cleanup();  	virtual bool	parseFile(const std::string &path, bool keep_contents = true); -	virtual bool	parseString(const std::string &xml, bool keep_contents = true);  	LLXmlTreeNode*	getRoot() { return mRoot; } @@ -200,8 +199,7 @@ public:  	LLXmlTreeParser(LLXmlTree* tree);  	virtual ~LLXmlTreeParser(); -	bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents); -	bool parseString(const std::string &xml, LLXmlTreeNode** root, bool keep_contents); +	bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents );  protected:  	const std::string& tabs(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c3f9a64fd6..4851efc9c4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11119,6 +11119,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>RenderAvatarFriendsOnly</key> +    <map> +        <key>Comment</key> +        <string>When enabled hides all avatars that aren't friends. Does not affect inworld control avatars (animeshes), nor self.</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <real>0</real> +    </map>      <key>RenderAvatarComplexityMode</key>      <map>          <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl index 1a85d70256..6791fe44d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl @@ -27,11 +27,11 @@  float random (vec2 uv)   { -    return 0; +    return 0.f;  }  float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)  {      collectedColor = vec4(0); -    return 0; +    return 0.f;  } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5585d04c69..e0a334df01 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3000,7 +3000,7 @@ void LLAppViewer::initStrings()  {  	std::string strings_file = "strings.xml";  	std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); -	if (strings_path_full.empty() || !gDirUtilp->fileExists(strings_path_full)) +	if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))  	{  		if (strings_path_full.empty())  		{ diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp index 16db32862d..29be2aaa6d 100644 --- a/indra/newview/llblocklist.cpp +++ b/indra/newview/llblocklist.cpp @@ -61,9 +61,8 @@ LLBlockList::LLBlockList(const Params& p)  	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(  									"menu_people_blocked_gear.xml",  									gMenuHolder, -									LLViewerMenuHolderGL::child_registry_t::instance(), -									true); -	if (context_menu) +									LLViewerMenuHolderGL::child_registry_t::instance()); +	if(context_menu)  	{  		mContextMenu = context_menu->getHandle();  	} diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 0c365d33c4..7d9fa2a475 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -131,7 +131,7 @@ public:  	static LLChatHistoryHeader* createInstance(const std::string& file_name)  	{  		LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; -		pInstance->buildFromFile(file_name, true); +		pInstance->buildFromFile(file_name);	  		return pInstance;  	} @@ -587,7 +587,7 @@ public:  		mUserNameTextBox = getChild<LLTextBox>("user_name");  		mTimeBoxTextBox = getChild<LLTextBox>("time_box"); -		mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance(), true); +		mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());          if (mInfoCtrl)          {              mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl)); @@ -1181,7 +1181,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)  LLView* LLChatHistory::getSeparator()  { -	LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance(), true); +	LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance());  	return separator;  } diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 030d24bed8..bc61fac00b 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -657,11 +657,12 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG      // This method reads the llsd based config file, and uses it to set       // members of a control group.      LLSD clpConfigLLSD; +     +    llifstream input_stream; +    input_stream.open(config_filename.c_str(), std::ios::in | std::ios::binary); -    std::string xml = gDirUtilp->getFileContents(config_filename); -    if (!xml.empty()) +    if(input_stream.is_open())      { -        std::stringstream input_stream(xml);          LLSDSerialize::fromXML(clpConfigLLSD, input_stream);          for(LLSD::map_iterator option_itr = clpConfigLLSD.beginMap();               option_itr != clpConfigLLSD.endMap();  diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index 7beefad191..fd1cda7a2c 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -85,6 +85,7 @@ public:      virtual bool shouldRenderRigged() const;  	virtual bool isImpostor();  +    virtual bool isBuddy() const { return false; }      bool mPlaying; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 32f0e185ce..a07827d395 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -370,6 +370,15 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  		return;  	} +    LLCachedControl<bool> debug_invisible(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (debug_invisible() +        && !avatarp->isControlAvatar() +        && !avatarp->isSelf() +        && !avatarp->isBuddy()) +    { +        return; +    } +      LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();  	bool impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();      // no shadows if the shadows are causing this avatar to breach the limit. @@ -723,6 +732,17 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} +    LLCachedControl<bool> friends_only(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (!single_avatar +        && friends_only() +        && !avatarp->isUIAvatar() +        && !avatarp->isControlAvatar() +        && !avatarp->isSelf() +        && !avatarp->isBuddy()) +    { +        return; +    } +  	bool impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;  	if (( avatarp->isInMuteList()  diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index a46cc0ce30..727f5592cd 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -886,11 +886,10 @@ const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()  	if (!params_initialized)  	{  		LLXMLNodePtr button_xml_node; -		static const std::string filename("favorites_bar_button.xml"); -		if (LLUICtrlFactory::getLayeredXMLNode(filename, button_xml_node, LLDir::CURRENT_SKIN, true)) +		if(LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", button_xml_node))  		{  			LLXUIParser parser; -			parser.readXUI(button_xml_node, button_params, filename); +			parser.readXUI(button_xml_node, button_params, "favorites_bar_button.xml");  		}  		params_initialized = true;  	} diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 72fbab406b..5461f98624 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -633,7 +633,7 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type, bool cl  void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )  {  	std::string filename(gDirUtilp->add(subdir, filename_in)); -	std::string expanded_filename = gDirUtilp->findSkinnedFilename(LLDir::HTML, filename); +	std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename);  	if (expanded_filename.empty())  	{ diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index f6ec455ae1..c94f87bddc 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -68,6 +68,8 @@  #include "lltabcontainer.h"  #include "lltextbox.h" +#include <filesystem> +  #include <boost/algorithm/string.hpp>  bool LLModelPreview::sIgnoreLoadedCallback = false; @@ -1067,6 +1069,29 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)      { //only replace given LoD          mModel[loaded_lod] = mModelLoader->mModelList;          mScene[loaded_lod] = mModelLoader->mScene; + +        // Duplicate the model if it is an internal bounding box model +        if (loaded_lod == LLModel::LOD_PHYSICS && +            mBaseModel.size() > 1 && // This makes sense for multiple models only +            mModelLoader->mModelList.size() == 1 && // Just on the off-chance +            mModelLoader->mScene.size() == 1 &&     // Just on the off-chance +            std::filesystem::path(mModelLoader->mFilename).filename() == "cube.dae") +        { +            // Create a copy of the just loaded model for each model in mBaseModel +            const LLModel* origin = mModelLoader->mModelList.front(); +            const LLModelInstance& mi = mModelLoader->mScene.begin()->second.front(); +            for (U32 i = 1; i < mBaseModel.size(); ++i) +            { +                LLPointer<LLModel> copy(new LLModel(origin->getParams(), origin->getDetail())); +                copy->mLabel = origin->mLabel; +                copy->copyVolumeFaces(origin); +                copy->mPosition = origin->mPosition; +                copy->mMaterialList = origin->mMaterialList; +                mModel[loaded_lod].push_back(copy); +                mScene[loaded_lod][mi.mTransform].push_back(LLModelInstance(copy, copy->mLabel, mi.mTransform, mi.mMaterial)); +            } +        } +          mVertexBuffer[loaded_lod].clear();          setPreviewLOD(loaded_lod); @@ -1163,6 +1188,17 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)                                      LLFloaterModelPreview::addStringToLog(out, false);                                  }                                  mModel[loaded_lod][idx]->mLabel = name; +                                // Rename the correspondent instance as well +                                [&]() +                                { +                                    for (auto& p : mScene[loaded_lod]) +                                        for (auto& i : p.second) +                                            if (i.mModel == mModel[loaded_lod][idx]) +                                            { +                                                i.mLabel = name; +                                                return; +                                            } +                                }();                              }                          }                      } diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 79a90c4f4c..75edac105a 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -594,7 +594,7 @@ LLSystemNotificationListItem::LLSystemNotificationListItem(const Params& p)      mSystemNotificationIcon(NULL),      mIsCaution(false)  { -    buildFromFile("panel_notification_list_item.xml", true); +    buildFromFile("panel_notification_list_item.xml");      mIsCaution = p.notification_priority >= NOTIFICATION_PRIORITY_HIGH;      if (mIsCaution)      { diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a8553b654e..36605fed7a 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -260,10 +260,16 @@ bool LLPanelNearByMedia::handleRightMouseDown(S32 x, S32 y, MASK mask)      S32 x_list, y_list;      localPointToOtherView(x, y, &x_list, &y_list, mMediaList);      if (mMoreLessBtn->getToggleState() -        && mMediaList->pointInView(x_list, y_list) -        && mMediaList->selectItemAt(x_list, y_list, mask)) +        && mMediaList->pointInView(x_list, y_list))      { -        if (mContextMenu) +        LLScrollListItem* hit_item = mMediaList->hitItem(x_list, y_list); +        bool selected = hit_item && hit_item->getSelected(); +        if (!selected) +        { +            selected = mMediaList->selectItemAt(x_list, y_list, mask); +        } +         +        if (selected && mContextMenu)          {              mContextMenu->buildDrawLabels();              mContextMenu->updateParent(LLMenuGL::sMenuContainer); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 28428112a1..91b8f0496e 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -67,6 +67,7 @@ const F32 PREVIEW_TEXTURE_MIN_ASPECT = 0.005f;  LLPreviewTexture::LLPreviewTexture(const LLSD& key)  	: LLPreview(key),  	  mLoadingFullImage( false ), +      mSavingMultiple(false),  	  mShowKeepDiscard(false),  	  mCopyToInv(false),  	  mIsCopyable(false), @@ -310,9 +311,12 @@ void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenam  	// remember the user-approved/edited file name.  	mSaveFileName = filenames[0]; +    mSavingMultiple = false;  	mLoadingFullImage = true;  	getWindow()->incBusyCount(); +    LL_DEBUGS("FileSaveAs") << "Scheduling saving file to " << mSaveFileName << LL_ENDL; +  	mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed.  	mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave,  		0, true, false, new LLUUID(mItemUUID), &mCallbackTextureList); @@ -322,35 +326,16 @@ void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenam  void LLPreviewTexture::saveMultipleToFile(const std::string& file_name)  {      std::string texture_location(gSavedSettings.getString("TextureSaveLocation"));	 -    std::string texture_name = file_name.empty() ? getItem()->getName() : file_name; -     -    std::string filepath; -    S32 i = 0; -    S32 err = 0; -    std::string extension(".png"); -    do -    { -        filepath = texture_location; -        filepath += gDirUtilp->getDirDelimiter(); -        filepath += texture_name; - -        if (i != 0) -        { -            filepath += llformat("_%.3d", i); -        } +    std::string texture_name = LLDir::getScrubbedFileName(file_name.empty() ? getItem()->getName() : file_name); -        filepath += extension; +    mSaveFileName = texture_location + gDirUtilp->getDirDelimiter() + texture_name + ".png"; -        llstat stat_info; -        err = LLFile::stat( filepath, &stat_info ); -        i++; -    } while (-1 != err);  // Search until the file is not found (i.e., stat() gives an error). -     -     -    mSaveFileName = filepath; +    mSavingMultiple = true;      mLoadingFullImage = true;      getWindow()->incBusyCount(); +    LL_DEBUGS("FileSaveAs") << "Scheduling saving file to " << mSaveFileName << LL_ENDL; +      mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed.      mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave,          0, true, false, new LLUUID(mItemUUID), &mCallbackTextureList); @@ -451,8 +436,39 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  	if( self && final && success )  	{ +        LL_DEBUGS("FileSaveAs") << "Saving file to " << self->mSaveFileName << LL_ENDL;  		const U32 ext_length = 3;  		std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length); + +        std::string filepath; +        if (self->mSavingMultiple) +        { +            std::string part_path = self->mSaveFileName.substr(0, self->mSaveFileName.length() - ext_length - 1); + +            S32 i = 0; +            S32 err = 0; +            do +            { +                filepath = part_path; + +                if (i != 0) +                { +                    filepath += llformat("_%.3d", i); +                } + +                filepath += "."; +                filepath += extension; + +                llstat stat_info; +                err = LLFile::stat(filepath, &stat_info); +                i++; +            } while (-1 != err);  // Search until the file is not found (i.e., stat() gives an error). +        } +        else +        { +            filepath = self->mSaveFileName; +        } +  		LLStringUtil::toLower(extension);  		// We only support saving in PNG or TGA format  		LLPointer<LLImageFormatted> image; @@ -468,13 +484,13 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  		if( image && !image->encode( src, 0 ) )  		{  			LLSD args; -			args["FILE"] = self->mSaveFileName; +			args["FILE"] = filepath;  			LLNotificationsUtil::add("CannotEncodeFile", args);  		} -		else if( image && !image->save( self->mSaveFileName ) ) +		else if( image && !image->save(filepath) )  		{  			LLSD args; -			args["FILE"] = self->mSaveFileName; +			args["FILE"] = filepath;  			LLNotificationsUtil::add("CannotWriteFile", args);  		}  		else @@ -482,6 +498,7 @@ void LLPreviewTexture::onFileLoadedForSave(bool success,  			self->mSavedFileTimer.reset();  			self->mSavedFileTimer.setTimerExpirySec( SECONDS_TO_SHOW_FILE_SAVED_MSG );  		} +        LL_DEBUGS("FileSaveAs") << "Done saving file to " << filepath << LL_ENDL;  		self->mSaveFileName.clear();  	} diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index fdc6dddb38..e8a0a43245 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -86,6 +86,7 @@ private:  	S32                 mImageOldBoostLevel;  	std::string			mSaveFileName;  	LLFrameTimer		mSavedFileTimer; +    bool				mSavingMultiple;  	bool				mLoadingFullImage;  	bool                mShowKeepDiscard;  	bool                mCopyToInv; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 5cf2e89c63..f6fadf276c 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -119,7 +119,7 @@ LLToast::LLToast(const LLToast::Params& p)  {  	mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); -	buildFromFile("panel_toast.xml", true); +	buildFromFile("panel_toast.xml");  	setCanDrag(false); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index f7bebf08aa..1f6a88cd95 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -266,9 +266,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )  	LLRect current_rect = getRect();  	setXMLFilename(""); -	buildFromFile("panel_notification.xml", true); +	buildFromFile("panel_notification.xml"); -    if (rect != LLRect::null) +    if(rect != LLRect::null)      {          this->setShape(rect);      } diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp index 49fbf885eb..f6fc9e7889 100644 --- a/indra/newview/lltoastscriptquestion.cpp +++ b/indra/newview/lltoastscriptquestion.cpp @@ -37,7 +37,7 @@ LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notificati  :  LLToastPanel(notification)  { -	buildFromFile("panel_script_question_toast.xml", true); +	buildFromFile("panel_script_question_toast.xml");  }  bool LLToastScriptQuestion::postBuild() diff --git a/indra/newview/lluiavatar.h b/indra/newview/lluiavatar.h index bcdffedef2..d9fe003155 100644 --- a/indra/newview/lluiavatar.h +++ b/indra/newview/lluiavatar.h @@ -39,6 +39,7 @@ public:      LLUIAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);  	virtual void 			initInstance(); // Called after construction to initialize the class.  	virtual	~LLUIAvatar(); +    virtual bool isBuddy() const { return false; }  };  #endif //LL_CONTROLAVATAR_H diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 67ce589142..9ed96a22d6 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -416,7 +416,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&  		return NULL ;  	} -	std::string full_path = gDirUtilp->findSkinnedFilename(LLDir::TEXTURES, filename); +	std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename);  	if (full_path.empty())  	{  		LL_WARNS() << "Failed to find local image file: " << filename << LL_ENDL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 873622d44e..d8712737ae 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -207,7 +207,7 @@ const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;  const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;  const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60; -const F32 MAX_ATTACHMENT_WAIT_TIME_SEC = 120; +const F32 MAX_ATTACHMENT_WAIT_TIME_SEC = 60;  const S32 MIN_NONTUNED_AVS = 5; @@ -680,7 +680,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mMutedAVColor(LLColor4::white /* used for "uninitialize" */),  	mFirstFullyVisible(true),      mFirstDecloudTime(-1.f), -	mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY),  	mFullyLoaded(false),  	mPreviousFullyLoaded(false),  	mFullyLoadedInitialized(false), @@ -2587,6 +2586,27 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL;  		return;  	} + +    LLCachedControl<bool> friends_only(gSavedSettings, "RenderAvatarFriendsOnly", false); +    if (friends_only() +        && !isUIAvatar() +        && !isControlAvatar() +        && !isSelf() +        && !isBuddy()) +    { +        if (mNameText) +        { +            mNameIsSet = false; +            mNameText->markDead(); +            mNameText = NULL; +            sNumVisibleChatBubbles--; +        } +        deleteParticleSource(); +        mVoiceVisualizer->setVoiceEnabled(false); + +        return; +    } +      // record time and refresh "tooSlow" status      updateTooSlow(); @@ -8287,7 +8307,7 @@ bool LLVOAvatar::updateIsFullyLoaded()                    );          // compare amount of attachments to one reported by simulator -        if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount != mSimAttachments.size()) +        if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount < mSimAttachments.size())          {              S32 attachment_count = getAttachmentCount();              if (mLastCloudAttachmentCount != attachment_count) @@ -8355,11 +8375,12 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)  	if (mFirstFullyVisible)  	{ +        F32 first_use_delay = FIRST_APPEARANCE_CLOUD_MIN_DELAY;          if (!isSelf() && loading)          {                  // Note that textures can causes 60s delay on thier own                  // so this delay might end up on top of textures' delay -                mFirstUseDelaySeconds = llclamp( +                first_use_delay = llclamp(                      mFirstAppearanceMessageTimer.getElapsedTimeF32(),                      FIRST_APPEARANCE_CLOUD_MIN_DELAY,                      FIRST_APPEARANCE_CLOUD_MAX_DELAY); @@ -8368,10 +8389,10 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)                  {                      // Impostors are less of a priority,                      // let them stay cloud longer -                    mFirstUseDelaySeconds *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER; +                    first_use_delay *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER;                  }          } -		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds); +		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > first_use_delay);  	}  	else  	{ @@ -9382,7 +9403,17 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe              << (attachment_id.isNull() ? "pending" : attachment_id.asString())              << " on point " << (S32)attach_point << LL_ENDL; -        mSimAttachments[attachment_id] = attach_point; +        if (attachment_id.notNull()) +        { +            mSimAttachments[attachment_id] = attach_point; +        } +        else +        { +            // at the moment viewer is only interested in non-null attachments +            LL_DEBUGS("AVAppearanceAttachments") << "AV " << getID() +                << " has null attachment on point " << (S32)attach_point +                << ", discarding" << LL_ENDL; +        }      }      // todo? Doesn't detect if attachments were switched @@ -11709,4 +11740,8 @@ F32 LLVOAvatar::getAverageGPURenderTime()      return ret;  } +bool LLVOAvatar::isBuddy() const +{ +    return LLAvatarTracker::instance().isBuddy(getID()); +}  diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f83ea59080..e5d232b792 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -253,6 +253,7 @@ public:  	virtual bool 	isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)  	virtual bool 	isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user) +    virtual bool 	isBuddy() const;  	// If this is an attachment, return the avatar it is attached to. Otherwise NULL.  	virtual const LLVOAvatar *getAttachedAvatar() const { return NULL; } @@ -424,7 +425,6 @@ protected:  private:  	bool			mFirstFullyVisible;      F32				mFirstDecloudTime; -	F32				mFirstUseDelaySeconds;  	LLFrameTimer	mFirstAppearanceMessageTimer;  	bool			mFullyLoaded; diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index c7b61edd1c..46bac63d93 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -110,6 +110,7 @@ private:  public:  	/*virtual*/ bool 	isSelf() const { return true; } +        virtual bool 	isBuddy() const { return false; }  	/*virtual*/ bool	isValid() const;  	//-------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 9697774fd9..9b2f644003 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3940,6 +3940,16 @@ function="World.EnvPreset"                       function="ToggleControl"                       parameter="AllowSelectAvatar" />                  </menu_item_check> +                <menu_item_check +                 label="Render Only Friends" +                 name="Render Only Friends"> +                    <menu_item_check.on_check +                     function="CheckControl" +                     parameter="RenderAvatarFriendsOnly" /> +                    <menu_item_check.on_click +                     function="ToggleControl" +                     parameter="RenderAvatarFriendsOnly" /> +                </menu_item_check>              </menu>              <menu               create_jump_keys="true" | 
