diff options
Diffstat (limited to 'indra')
43 files changed, 708 insertions, 396 deletions
| diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 9cb830a2db..54049b5545 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -392,11 +392,21 @@ class LLManifest(object):              raise ManifestError, "Should be something at path " + path          self.created_paths.append(path) -    def put_in_file(self, contents, dst): +    def put_in_file(self, contents, dst, src=None):          # write contents as dst -        f = open(self.dst_path_of(dst), "wb") -        f.write(contents) -        f.close() +        dst_path = self.dst_path_of(dst) +        f = open(dst_path, "wb") +        try: +            f.write(contents) +        finally: +            f.close() + +        # Why would we create a file in the destination tree if not to include +        # it in the installer? The default src=None (plus the fact that the +        # src param is last) is to preserve backwards compatibility. +        if src: +            self.file_list.append([src, dst_path]) +        return dst_path      def replace_in(self, src, dst=None, searchdict={}):          if dst == None: diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 1cdddf0d5b..b1b75776a7 100755 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -356,8 +356,8 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)  {  	std::string controlname = getRectControlName(name);  	LLFloater::getControlGroup()->declareRect(controlname, LLRect(), -												 llformat("Window Size for %s", name.c_str()), -												 TRUE); +											  llformat("Window Size for %s", name.c_str()), +											  LLControlVariable::PERSIST_NONDFT);  	return controlname;  } @@ -367,7 +367,7 @@ std::string LLFloaterReg::declarePosXControl(const std::string& name)  	LLFloater::getControlGroup()->declareF32(controlname,   											10.f,  											llformat("Window X Position for %s", name.c_str()), -											TRUE); +											LLControlVariable::PERSIST_NONDFT);  	return controlname;  } @@ -377,7 +377,7 @@ std::string LLFloaterReg::declarePosYControl(const std::string& name)  	LLFloater::getControlGroup()->declareF32(controlname,  											10.f,  											llformat("Window Y Position for %s", name.c_str()), -											TRUE); +											LLControlVariable::PERSIST_NONDFT);  	return controlname;  } @@ -404,7 +404,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)  	std::string controlname = getVisibilityControlName(name);  	LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,  												 llformat("Window Visibility for %s", name.c_str()), -												 TRUE); +												 LLControlVariable::PERSIST_NONDFT);  	return controlname;  } @@ -414,7 +414,7 @@ std::string LLFloaterReg::declareDockStateControl(const std::string& name)  	std::string controlname = getDockStateControlName(name);  	LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,  												 llformat("Window Docking state for %s", name.c_str()), -												 TRUE); +												 LLControlVariable::PERSIST_NONDFT);  	return controlname;  } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 1789f003b9..a1853ca1f7 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -214,7 +214,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica  		}  		else  		{ -			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", TRUE); +			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT);  			mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name);  		}  	} diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index cc10ed5bbd..e02bf552aa 100755 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -32,7 +32,7 @@  #define MAX_PATH MAXPATHLEN  #endif -// these numbers *may* get serialized (really??), so we need to be explicit +// these numbers are read from settings_files.xml, so we need to be explicit  typedef enum ELLPath  {  	LL_PATH_NONE = 0, diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 666c03e9ff..16f2290787 100755 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -132,14 +132,14 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)  LLControlVariable::LLControlVariable(const std::string& name, eControlType type,  							 LLSD initial, const std::string& comment, -							 bool persist, bool hidefromsettingseditor) +							 ePersist persist, bool hidefromsettingseditor)  	: mName(name),  	  mComment(comment),  	  mType(type),  	  mPersist(persist),  	  mHideFromSettingsEditor(hidefromsettingseditor)  { -	if (mPersist && mComment.empty()) +	if ((persist != PERSIST_NO) && mComment.empty())  	{  		llerrs << "Must supply a comment for control " << mName << llendl;  	} @@ -260,7 +260,7 @@ void LLControlVariable::setDefaultValue(const LLSD& value)  	}  } -void LLControlVariable::setPersist(bool state) +void LLControlVariable::setPersist(ePersist state)  {  	mPersist = state;  } @@ -292,10 +292,29 @@ void LLControlVariable::resetToDefault(bool fire_signal)  	}  } -bool LLControlVariable::isSaveValueDefault() -{  -    return (mValues.size() ==  1)  -        || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0])); +bool LLControlVariable::shouldSave(bool nondefault_only) +{ +	// This method is used to decide whether we should save a given +	// variable. Two of the three values of mPersist are easy. +	if (mPersist == PERSIST_NO) +		return false; + +	if (mPersist == PERSIST_ALWAYS) +		return true; + +	// PERSIST_NONDFT +	// If caller doesn't need us to filter, just save. +	if (! nondefault_only) +		return true; + +	// PERSIST_NONDFT: caller only wants us to save this variable if its value +	// differs from default. +	if (isDefault())                // never been altered +		return false; + +	// We've set at least one other value: compare it to default. Save only if +	// they differ. +	return ! llsd_compare(getSaveValue(), getDefault());  }  LLSD LLControlVariable::getSaveValue() const @@ -355,12 +374,12 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum)  	return mTypeString[typeenum];  } -BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor) +LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor)  {  	LLControlVariable* existing_control = getControl(name);  	if (existing_control)   	{ -		if (persist && existing_control->isType(type)) +		if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type))  		{  			if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val))  			{ @@ -374,66 +393,66 @@ BOOL LLControlGroup::declareControl(const std::string& name, eControlType type,  		{  			llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;  		} - 		return TRUE; + 		return existing_control;  	}  	// if not, create the control and add it to the name table  	LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor);  	mNameTable[name] = control;	 -	return TRUE; +	return control;  } -BOOL LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist);  } -BOOL LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_S32, initial_val, comment, persist);  } -BOOL LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_F32, initial_val, comment, persist);  } -BOOL LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);  } -BOOL LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_STRING, initial_val, comment, persist);  } -BOOL LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);  } -BOOL LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);  } -BOOL LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);  } -BOOL LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist ) +LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )  {  	return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);  } -BOOL LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist ) +LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )  {  	return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);  } -BOOL LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist ) +LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist )  {  	return declareControl(name, TYPE_LLSD, initial_val, comment, persist);  } @@ -664,11 +683,11 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require  			switch(declare_as)  			{  			case TYPE_COL4: -				declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST); +				declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO);  				break;  			case TYPE_STRING:  			default: -				declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST); +				declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO);  				break;  			}  		} @@ -805,21 +824,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only  		{  			llwarns << "Tried to save invalid control: " << iter->first << llendl;  		} - -		if( control && control->isPersisted() ) +		else if( control->shouldSave(nondefault_only) )  		{ -			if (!(nondefault_only && (control->isSaveValueDefault()))) -			{ -				settings[iter->first]["Type"] = typeEnumToString(control->type()); -				settings[iter->first]["Comment"] = control->getComment(); -				settings[iter->first]["Value"] = control->getSaveValue(); -				++num_saved; -			} -			else -			{ -				// Debug spam -				// llinfos << "Skipping " << control->getName() << llendl; -			} +			settings[iter->first]["Type"] = typeEnumToString(control->type()); +			settings[iter->first]["Comment"] = control->getComment(); +			settings[iter->first]["Value"] = control->getSaveValue(); +			++num_saved;  		}  	}  	llofstream file; @@ -862,13 +872,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  	for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)  	{ -		bool persist = true; +		LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT;  		std::string const & name = itr->first;  		LLSD const & control_map = itr->second;  		if(control_map.has("Persist"))   		{ -			persist = control_map["Persist"].asInteger(); +			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 @@ -887,6 +898,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  		LLControlVariable* existing_control = getControl(name);  		if(existing_control)  		{ +			// set_default_values is true when we're loading the initial, +			// immutable files from app_settings, e.g. settings.xml.  			if(set_default_values)  			{  				// Override all previously set properties of this control. @@ -908,6 +921,9 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  			}  			else if(existing_control->isPersisted())  			{ +				// save_values is specifically false for (e.g.) +				// SessionSettingsFile and UserSessionSettingsFile -- in other +				// words, for a file that's supposed to be transient.  				existing_control->setValue(control_map["Value"], save_values);  			}  			// *NOTE: If not persisted and not setting defaults,  @@ -915,6 +931,39 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  		}  		else  		{ +			// We've never seen this control before. Either we're loading up +			// the initial set of default settings files (set_default_values) +			// -- or we're loading user settings last saved by a viewer that +			// supports a superset of the variables we know. +			// CHOP-962: if we're loading an unrecognized user setting, make +			// sure we save it later. If you try an experimental viewer, tweak +			// a new setting, briefly revert to an old viewer, then return to +			// the new one, we don't want the old viewer to discard the +			// setting you changed. +			if (! set_default_values) +			{ +				// Using PERSIST_ALWAYS insists that saveToFile() (which calls +				// LLControlVariable::shouldSave()) must save this control +				// variable regardless of its value. We can safely set this +				// LLControlVariable persistent because the 'persistent' flag +				// is not itself persisted! +				persist = LLControlVariable::PERSIST_ALWAYS; +				// We want to mention unrecognized user settings variables +				// (e.g. from a newer version of the viewer) in the log. But +				// we also arrive here for Boolean variables generated by +				// the notifications subsystem when the user checks "Don't +				// show me this again." These aren't declared in settings.xml; +				// they're actually named for the notification they suppress. +				// We don't want to mention those. Apologies, this is a bit of +				// a hack: we happen to know that user settings go into an +				// LLControlGroup whose name is "Global". +				if (getKey() == "Global") +				{ +					LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey() +											   << " settings variable " << name << LL_ENDL; +				} +			} +  			declareControl(name,   						   typeStringToEnum(control_map["Type"].asString()),   						   control_map["Value"],  @@ -923,7 +972,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  						   hidefromsettingseditor  						   );  		} -		 +  		++validitems;  	} diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index ee7d1d50b7..e1f9be80dd 100755 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -72,8 +72,6 @@ class LLVector3d;  class LLColor4;  class LLColor3; -const BOOL NO_PERSIST = FALSE; -  typedef enum e_control_type  {  	TYPE_U32 = 0, @@ -100,21 +98,28 @@ public:  	typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;  	typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t; +	enum ePersist +	{ +		PERSIST_NO,                 // don't save this var +		PERSIST_NONDFT,             // save this var if differs from default +		PERSIST_ALWAYS              // save this var even if has default value +	}; +  private:  	std::string		mName;  	std::string		mComment;  	eControlType	mType; -	bool			mPersist; +	ePersist		mPersist;  	bool			mHideFromSettingsEditor;  	std::vector<LLSD> mValues; -	 +  	commit_signal_t mCommitSignal;  	validate_signal_t mValidateSignal;  public:  	LLControlVariable(const std::string& name, eControlType type,  					  LLSD initial, const std::string& comment, -					  bool persist = true, bool hidefromsettingseditor = false); +					  ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false);  	virtual ~LLControlVariable(); @@ -131,8 +136,8 @@ public:  	validate_signal_t* getValidateSignal() { return &mValidateSignal; }  	bool isDefault() { return (mValues.size() == 1); } -	bool isSaveValueDefault(); -	bool isPersisted() { return mPersist; } +	bool shouldSave(bool nondefault_only); +	bool isPersisted() { return mPersist != PERSIST_NO; }  	bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }  	LLSD get()			const	{ return getValue(); }  	LLSD getValue()		const	{ return mValues.back(); } @@ -142,7 +147,7 @@ public:  	void set(const LLSD& val)	{ setValue(val); }  	void setValue(const LLSD& value, bool saved_value = TRUE);  	void setDefaultValue(const LLSD& value); -	void setPersist(bool state); +	void setPersist(ePersist);  	void setHiddenFromSettingsEditor(bool hide);  	void setComment(const std::string& comment); @@ -207,19 +212,19 @@ public:  		virtual void apply(const std::string& name, LLControlVariable* control) = 0;  	};  	void applyToAll(ApplyFunctor* func); -	 -	BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE); -	BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  BOOL persist = TRUE); -	BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE); -	BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE); + +	LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE); +	LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); +	LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);  	std::string getString(const std::string& name);  	std::string getText(const std::string& name); @@ -368,7 +373,7 @@ private:  		init_value = convert_to_llsd(default_value);  		if(type < TYPE_COUNT)  		{ -			group.declareControl(name, type, init_value, comment, FALSE); +			group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO);  			return true;  		}  		return false; diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index ede81956ec..c273773c9b 100755 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -128,7 +128,11 @@ namespace tut  	template<> template<>  	void control_group_t::test<3>()  	{ -		int results = mCG->loadFromFile(mTestConfigFile.c_str()); +		// Pass default_values = true. This tells loadFromFile() we're loading +		// a default settings file that declares variables, rather than a user +		// settings file. When loadFromFile() encounters an unrecognized user +		// settings variable, it forcibly preserves it (CHOP-962). +		int results = mCG->loadFromFile(mTestConfigFile.c_str(), true);  		LLControlVariable* control = mCG->getControl("TestSetting");  		LLSD new_value = 13;  		control->setValue(new_value, FALSE); diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 7ab7787d77..74117dbd85 100755 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -22,7 +22,8 @@      <map>        <key>count</key>        <integer>1</integer> -      <!-- Special case. Not mapped to a setting. --> +      <key>map-to</key> +      <string>CmdLineChannel</string>      </map>      <key>console</key> @@ -96,6 +97,8 @@  0 - low, 1 - medium, 2 - high, 3 - ultra</string>        <key>count</key>        <integer>1</integer> +      <key>map-to</key> +      <string>RenderQualityPerformance</string>      </map>      <key>grid</key> @@ -370,7 +373,8 @@        <boolean>true</boolean>        <key>last_option</key>        <boolean>true</boolean> -      <!-- Special case. Not mapped to a setting. --> +      <key>map-to</key> +      <string>CmdLineLoginLocation</string>      </map>      <key>url</key> @@ -381,7 +385,8 @@        <integer>1</integer>        <key>last_option</key>        <boolean>true</boolean> -      <!-- Special case. Not mapped to a setting. --> +      <key>map-to</key> +      <string>CmdLineLoginLocation</string>      </map>      <key>usersessionsettings</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 344079b640..4c8860ffe7 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -126,6 +126,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>AnalyzePerformance</key> +    <map> +      <key>Comment</key> +      <string>Request performance analysis for a particular viewer run</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>AnimateTextures</key>      <map>        <key>Comment</key> @@ -1738,6 +1749,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>CmdLineChannel</key> +    <map> +      <key>Comment</key> +      <string>Command line specified channel name</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string /> +    </map>      <key>CmdLineDisableVoice</key>      <map>        <key>Comment</key> @@ -1784,6 +1806,17 @@          <string />        </array>      </map> +    <key>CmdLineLoginLocation</key> +    <map> +      <key>Comment</key> +      <string>Startup destination requested on command line</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string/> +    </map>      <key>ConnectAsGod</key>      <map>        <key>Comment</key> @@ -1916,6 +1949,17 @@        <key>Value</key>        <integer>262144</integer>      </map> +    <key>CrashOnStartup</key> +    <map> +      <key>Comment</key> +      <string>User-requested crash on viewer startup</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>CreateToolCopyCenters</key>      <map>        <key>Comment</key> @@ -2158,6 +2202,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>DebugSession</key> +    <map> +      <key>Comment</key> +      <string>Request debugging for a particular viewer session</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DebugShowColor</key>      <map>        <key>Comment</key> @@ -2972,6 +3027,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>DisableCrashLogger</key> +    <map> +      <key>Comment</key> +      <string>Do not send crash report to Linden server</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DisableMouseWarp</key>      <map>        <key>Comment</key> @@ -5217,6 +5283,28 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>LogMetrics</key> +    <map> +      <key>Comment</key> +      <string>Log viewer metrics</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string/> +    </map> +    <key>LogPerformance</key> +    <map> +      <key>Comment</key> +      <string>Log performance analysis for a particular viewer run</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>LogTextureNetworkTraffic</key>      <map>        <key>Comment</key> @@ -6394,6 +6482,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>NoQuickTime</key> +    <map> +      <key>Comment</key> +      <string>Disable QuickTime for a particular viewer run</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>NoVerifySSLCert</key>      <map>        <key>Comment</key> @@ -9642,6 +9741,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>ReplaySession</key> +    <map> +      <key>Comment</key> +      <string>Request replay of previously-recorded pilot file</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>RotateRight</key>      <map>        <key>Comment</key> @@ -12858,12 +12968,13 @@      <key>UserLoginInfo</key>      <map>        <key>Comment</key> -      <string>Users loging data.</string> +      <string>User login data.</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key>        <string>LLSD</string>        <key>Value</key> +      <string/>      </map>      <key>VFSOldSize</key>      <map> diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml index bfc09286e3..4a9e522a96 100755 --- a/indra/newview/app_settings/settings_files.xml +++ b/indra/newview/app_settings/settings_files.xml @@ -4,6 +4,9 @@      <file name="Global"            file_name="settings.xml"            required="true"/> +    <file name="Global" +          file_name="settings_install.xml" +          required="false"/>      <file name="PerAccount"            file_name="settings_per_account.xml"            required="true"/> diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index d8440eebf1..c23401d5a6 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -121,37 +121,21 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"  export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" -# Have to deal specially with gridargs.dat; typical contents look like: -# --channel "Second Life Test"  --settings settings_test.xml -# Simply embedding $(<etc/gridargs.dat) into a command line treats each of -# Second, Life and Developer as separate args -- no good. We need bash to -# process quotes using eval. -# First, check if we have been instructed to skip reading in gridargs.dat: -skip_gridargs=false -argnum=0 +# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. +# The gridargs.dat file is no more, but we still want to avoid breaking +# scripts that invoke this one with --skip-gridargs. +ARGS=()  for ARG in "$@"; do -    if [ "--skip-gridargs" == "$ARG" ]; then -        skip_gridargs=true -    else -        ARGS[$argnum]="$ARG" -        argnum=$(($argnum+1)) +    if [ "--skip-gridargs" != "$ARG" ]; then +        ARGS[${#ARGS[*]}]="$ARG"      fi  done -# Second, read it without scanning, then scan that string. Break quoted words -# into a bash array. Note that if gridargs.dat is empty, or contains only -# whitespace, the resulting gridargs array will be empty -- zero entries -- -# therefore "${gridargs[@]}" entirely vanishes from the command line below, -# just as we want. -if ! $skip_gridargs ; then -    eval gridargs=("$(<etc/gridargs.dat)") -fi -  # Run the program.  # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the -# command line. But DO quote "$@": preserve separate args as individually -# quoted. Similar remarks about the contents of gridargs. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}" +# command line. But DO quote "${ARGS[@]}": preserve separate args as +# individually quoted. +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}"  LL_RUN_ERR=$?  # Handle any resulting errors diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3e94c5edf7..05f3824485 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -433,7 +433,7 @@ void LLAgent::init()  {  	mMoveTimer.start(); -	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE); +	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO);  	gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));  	// *Note: this is where LLViewerCamera::getInstance() used to be constructed. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f92274dbbd..b2aadf9cc0 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -668,7 +668,6 @@ LLAppViewer::LLAppViewer() :  	mSecondInstance(false),  	mSavedFinalSnapshot(false),  	mSavePerAccountSettings(false),		// don't save settings on logout unless login succeeded. -	mForceGraphicsDetail(false),  	mQuitRequested(false),  	mLogoutRequestSent(false),  	mYieldTime(-1), @@ -2307,17 +2306,24 @@ void LLAppViewer::loadColorSettings()  	LLUIColorTable::instance().loadFromSettings();  } +namespace +{ +    void handleCommandLineError(LLControlGroupCLP& clp) +    { +		llwarns << "Error parsing command line options. Command Line options ignored."  << llendl; + +		llinfos << "Command line usage:\n" << clp << llendl; + +		OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()), +					 LLStringUtil::null, +					 OSMB_OK); +    } +} // anonymous namespace +  bool LLAppViewer::initConfiguration()  {	  	//Load settings files list  	std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); -	//LLControlGroup settings_control("SettingsFiles"); -	//llinfos << "Loading settings file list " << settings_file_list << llendl; -	//if (0 == settings_control.loadFromFile(settings_file_list)) -	//{ - //       llerrs << "Cannot load default configuration file " << settings_file_list << llendl; -	//} -  	LLXMLNodePtr root;  	BOOL success  = LLXMLNode::parseFile(settings_file_list, root, NULL);  	if (!success) @@ -2376,9 +2382,7 @@ bool LLAppViewer::initConfiguration()  	{  		c->setValue(true, false);  	} -#endif -#ifndef	LL_RELEASE_FOR_DOWNLOAD  	gSavedSettings.setBOOL("QAMode", TRUE );  	gSavedSettings.setS32("WatchdogEnabled", 0);  #endif @@ -2414,13 +2418,7 @@ bool LLAppViewer::initConfiguration()  	if(!initParseCommandLine(clp))  	{ -		llwarns	<< "Error parsing command line options.	Command	Line options ignored."  << llendl; -		 -		llinfos	<< "Command	line usage:\n" << clp << llendl; - -		std::ostringstream msg; -		msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage(); -		OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); +		handleCommandLineError(clp);  		return false;  	} @@ -2467,12 +2465,16 @@ bool LLAppViewer::initConfiguration()  	loadSettingsFromDirectory("UserSession");  	// - apply command line settings  -	clp.notify();  +	if (! clp.notify()) +	{ +		handleCommandLineError(clp); +		return false; +	}  	// Register the core crash option as soon as we can  	// if we want gdb post-mortem on cores we need to be up and running  	// ASAP or we might miss init issue etc. -	if(clp.hasOption("disablecrashlogger")) +	if(gSavedSettings.getBOOL("DisableCrashLogger"))  	{  		llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << llendl;  		LLAppViewer::instance()->disableCrashlogger(); @@ -2545,91 +2547,52 @@ bool LLAppViewer::initConfiguration()          }      } -    if(clp.hasOption("channel")) -    { -		LLVersionInfo::resetChannel(clp.getOption("channel")[0]); +	std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); +	if(! CmdLineChannel.empty()) +	{ +		LLVersionInfo::resetChannel(CmdLineChannel);  	}  	// If we have specified crash on startup, set the global so we'll trigger the crash at the right time -	if(clp.hasOption("crashonstartup")) -	{ -		gCrashOnStartup = TRUE; -	} +	gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup"); -	if (clp.hasOption("logperformance")) +	if (gSavedSettings.getBOOL("LogPerformance"))  	{  		LLFastTimer::sLog = TRUE;  		LLFastTimer::sLogName = std::string("performance");		  	} -	 -	if (clp.hasOption("logmetrics")) - 	{ - 		LLFastTimer::sMetricLog = TRUE ; -		// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test -		// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...) -		std::string test_name = clp.getOption("logmetrics")[0]; + +	std::string test_name(gSavedSettings.getString("LogMetrics")); +	if (! test_name.empty()) +	{ +		LLFastTimer::sMetricLog = TRUE ; +		// '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test +		// In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)  		llinfos << "'--logmetrics' argument : " << test_name << llendl; -		if (test_name == "") -		{ -			llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl; -			LLFastTimer::sLogName = DEFAULT_METRIC_NAME; -		} -		else -		{ -			LLFastTimer::sLogName = test_name; -		} +		LLFastTimer::sLogName = test_name;   	}  	if (clp.hasOption("graphicslevel"))  	{ -		const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel"); -        if(value.size() != 1) -        { -			llwarns << "Usage: -graphicslevel <0-3>" << llendl; -        } -        else -        { -			std::string detail = value.front(); -			mForceGraphicsDetail = TRUE; -			 -			switch (detail.c_str()[0]) -			{ -				case '0':  -					gSavedSettings.setU32("RenderQualityPerformance", 0);		 -					break; -				case '1':  -					gSavedSettings.setU32("RenderQualityPerformance", 1);		 -					break; -				case '2':  -					gSavedSettings.setU32("RenderQualityPerformance", 2);		 -					break; -				case '3':  -					gSavedSettings.setU32("RenderQualityPerformance", 3);		 -					break; -				default: -					mForceGraphicsDetail = FALSE; -					llwarns << "Usage: -graphicslevel <0-3>" << llendl; -					break; -			} -        } -	} - -	if (clp.hasOption("analyzeperformance")) -	{ -		LLFastTimerView::sAnalyzePerformance = TRUE; +		// User explicitly requested --graphicslevel on the command line. We +		// expect this switch has already set RenderQualityPerformance. Check +		// that value for validity. +		U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance"); +		if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel)) +		{ +			// graphicslevel is valid: save it and engage it later. Capture +			// the requested value separately from the settings variable +			// because, if this is the first run, LLViewerWindow's constructor +			// will call LLFeatureManager::applyRecommendedSettings(), which +			// overwrites this settings variable! +			mForceGraphicsLevel = graphicslevel; +		}  	} -	if (clp.hasOption("replaysession")) -	{ -		gAgentPilot.setReplaySession(TRUE); -	} +	LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); +	gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession")); -	if (clp.hasOption("nonotifications")) -	{ -		gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false); -	} -	 -	if (clp.hasOption("debugsession")) +	if (gSavedSettings.getBOOL("DebugSession"))  	{  		gDebugSession = TRUE;  		gDebugGL = TRUE; @@ -2654,20 +2617,16 @@ bool LLAppViewer::initConfiguration()      // What can happen is that someone can use IE (or potentially       // other browsers) and do the rough equivalent of command       // injection and steal passwords. Phoenix. SL-55321 -    if(clp.hasOption("url")) -    { -		LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0])); -		if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)  -		{   -			LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid()); -			 -		}   -    } -    else if(clp.hasOption("slurl")) -    { -		LLSLURL start_slurl(clp.getOption("slurl")[0]); +	std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation")); +	if(! CmdLineLoginLocation.empty()) +	{ +		LLSLURL start_slurl(CmdLineLoginLocation);  		LLStartUp::setStartSLURL(start_slurl); -    } +		if(start_slurl.getType() == LLSLURL::LOCATION)  +		{   +			LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); +		} +	}  	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");  	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) @@ -2810,9 +2769,8 @@ bool LLAppViewer::initConfiguration()  		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;  		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));  	} -	else if (   (   clp.hasOption("login") || clp.hasOption("autologin")) -			 && !clp.hasOption("url") -			 && !clp.hasOption("slurl")) +	else if ((clp.hasOption("login") || clp.hasOption("autologin")) +			 && gSavedSettings.getString("CmdLineLoginLocation").empty())  	{  		// If automatic login from command line with --login switch  		// init StartSLURL location. @@ -3186,11 +3144,12 @@ bool LLAppViewer::initWindow()  	// Initialize GL stuff  	// -	if (mForceGraphicsDetail) +	if (mForceGraphicsLevel)  	{ -		LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false); +		LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); +		gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);  	} -			 +  	// Set this flag in case we crash while initializing GL  	gSavedSettings.setBOOL("RenderInitError", TRUE);  	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index cd91ae8b2b..3af360b529 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -32,6 +32,7 @@  #include "llsys.h"			// for LLOSInfo  #include "lltimer.h"  #include "llappcorehttp.h" +#include <boost/optional.hpp>  class LLCommandLineParser;  class LLFrameTimer; @@ -258,7 +259,7 @@ private:  	bool mSavedFinalSnapshot;  	bool mSavePerAccountSettings;		// only save per account settings if login succeeded -	bool mForceGraphicsDetail; +	boost::optional<U32> mForceGraphicsLevel;      bool mQuitRequested;				// User wants to quit, may have modified documents open.      bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim. diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 4d340cafa9..c7b437598c 100755 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -148,28 +148,13 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp)  	// The next two lines add the support for parsing the mac -psn_XXX arg.  	clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number");  	clp.setCustomParser(parse_psn); -	 -    // First read in the args from arguments txt. -    const char* filename = "arguments.txt"; -	llifstream ifs(filename, llifstream::binary); -	if (!ifs.is_open()) -	{ -		llwarns << "Unable to open file" << filename << llendl; -		return false; -	} -	 -	if(clp.parseCommandLineFile(ifs) == false) -	{ -		return false; -	} -	// Then parse the user's command line, so that any --url arg can appear last -	// Succesive calls to clp.parse... will NOT override earlier options.  +	// parse the user's command line  	if(clp.parseCommandLine(gArgC, gArgV) == false)  	{  		return false;  	} -    	 +  	// Get the user's preferred language string based on the Mac OS localization mechanism.  	// To add a new localization:  		// go to the "Resources" section of the project diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 17d403bbe1..a6384ded12 100755 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -38,16 +38,23 @@  #endif  #include <boost/program_options.hpp> +#include <boost/lexical_cast.hpp>  #include <boost/bind.hpp> -#include<boost/tokenizer.hpp> +#include <boost/tokenizer.hpp> +#include <boost/assign/list_of.hpp>  #if _MSC_VER  #   pragma warning(pop)  #endif  #include "llsdserialize.h" +#include "llerror.h" +#include "stringize.h" +#include <string> +#include <set>  #include <iostream>  #include <sstream> +#include <typeinfo>  #include "llcontrol.h" @@ -63,10 +70,22 @@ namespace po = boost::program_options;  // This could be good or bad, and probably won't matter for most use cases.  namespace   { +    // List of command-line switches that can't map-to settings variables. +    // Going forward, we want every new command-line switch to map-to some +    // settings variable. This list is used to validate that. +    const std::set<std::string> unmapped_options = boost::assign::list_of +        ("help") +        ("set") +        ("setdefault") +        ("settings") +        ("sessionsettings") +        ("usersessionsettings") +    ; +      po::options_description gOptionsDesc;      po::positional_options_description gPositionalOptions;  	po::variables_map gVariableMap; -     +      const LLCommandLineParser::token_vector_t gEmptyValue;      void read_file_into_string(std::string& str, const std::basic_istream < char >& file) @@ -384,9 +403,19 @@ bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char >      return parseCommandLineString(args);  } -void LLCommandLineParser::notify() +bool LLCommandLineParser::notify()  { -    po::notify(gVariableMap);     +    try +    { +        po::notify(gVariableMap); +        return true; +    } +    catch (const LLCLPError& e) +    { +        llwarns << "Caught Error: " << e.what() << llendl; +        mErrorMsg = e.what(); +        return false; +    }  }  void LLCommandLineParser::printOptions() const @@ -428,43 +457,129 @@ const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const  //----------------------------------------------------------------------------  // LLControlGroupCLP defintions  //---------------------------------------------------------------------------- +namespace { +LLCommandLineParser::token_vector_t::value_type +onevalue(const std::string& option, +         const LLCommandLineParser::token_vector_t& value) +{ +    if (value.empty()) +    { +        // What does it mean when the user specifies a command-line switch +        // that requires a value, but omits the value? Complain. +        throw LLCLPError(STRINGIZE("No value specified for --" << option << "!")); +    } +    else if (value.size() > 1) +    { +        llwarns << "Ignoring extra tokens specified for --" +                << option << "." << llendl;  +    } +    return value[0]; +} + +void badvalue(const std::string& option, +              const std::string& varname, +              const std::string& type, +              const std::string& value) +{ +    // If the user passes an unusable value for a command-line switch, it +    // seems like a really bad idea to just ignore it, even with a log +    // warning. +    throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option +                               << "' for variable '" << varname << "' of type " << type +                               << ": '" << value << "'")); +} + +template <typename T> +T convertTo(const std::string& option, +            const std::string& varname, +            const LLCommandLineParser::token_vector_t::value_type& value) +{ +    try +    { +        return boost::lexical_cast<T>(value); +    } +    catch (const boost::bad_lexical_cast&) +    { +        badvalue(option, varname, typeid(T).name(), value); +        // bogus return; compiler unaware that badvalue() won't return +        return T(); +    } +} +  void setControlValueCB(const LLCommandLineParser::token_vector_t& value,  -                       const std::string& opt_name,  -                       LLControlGroup* ctrlGroup) +                       const std::string& option,  +                       LLControlVariable* ctrl)  { -    // *FIX: Do sematic conversion here. +    // *FIX: Do semantic conversion here.      // LLSD (ImplString) Is no good for doing string to type conversion for...      // booleans      // compound types      // ?... -    LLControlVariable* ctrl = ctrlGroup->getControl(opt_name);      if(NULL != ctrl)      {          switch(ctrl->type())          {          case TYPE_BOOLEAN: -            if(value.size() > 1) +            if (value.empty())              { -                llwarns << "Ignoring extra tokens." << llendl;  +                // Boolean-valued command-line switches are unusual. If you +                // simply specify the switch without an explicit value, we can +                // infer you mean 'true'. +                ctrl->setValue(LLSD(true), false);              } -               -            if(value.size() > 0) +            else              { +                // Only call onevalue() AFTER handling value.empty() case! +                std::string token(onevalue(option, value)); +                              // There's a token. check the string for true/false/1/0 etc.                  BOOL result = false; -                BOOL gotSet = LLStringUtil::convertToBOOL(value[0], result); -                if(gotSet) +                BOOL gotSet = LLStringUtil::convertToBOOL(token, result); +                if (gotSet)                  {                      ctrl->setValue(LLSD(result), false);                  } +                else +                { +                    badvalue(option, ctrl->getName(), "bool", token); +                } +            } +            break; + +        case TYPE_U32: +        { +            std::string token(onevalue(option, value)); +            // To my surprise, for an unsigned target, lexical_cast() doesn't +            // complain about an input string such as "-17". In that case, you +            // get a very large positive result. So for U32, make sure there's +            // no minus sign! +            if (token.find('-') == std::string::npos) +            { +                ctrl->setValue(LLSD::Integer(convertTo<U32>(option, ctrl->getName(), token)), +                               false);              }              else              { -                ctrl->setValue(LLSD(true), false); +                badvalue(option, ctrl->getName(), "unsigned", token);              }              break; +        } + +        case TYPE_S32: +            ctrl->setValue(convertTo<S32>(option, ctrl->getName(), +                                          onevalue(option, value)), false); +            break; + +        case TYPE_F32: +            ctrl->setValue(convertTo<F32>(option, ctrl->getName(), +                                          onevalue(option, value)), false); +            break; +        // It appears that no one has yet tried to define a command-line +        // switch mapped to a settings variable of TYPE_VEC3, TYPE_VEC3D, +        // TYPE_RECT, TYPE_COL4, TYPE_COL3. Such types would certainly seem to +        // call for a bit of special handling here...          default:              {                  // For the default types, let llsd do the conversion. @@ -481,16 +596,9 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,                      ctrl->setValue(llsdArray, false);                  } -                else if(value.size() > 0) +                else                  { -					if(value.size() > 1) -					{ -						llwarns << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << llendl;  -					} - -                    LLSD llsdValue; -                    llsdValue.assign(LLSD::String(value[0])); -                    ctrl->setValue(llsdValue, false); +                    ctrl->setValue(onevalue(option, value), false);                  }              }              break; @@ -498,12 +606,14 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,      }      else      { -        llwarns << "Command Line option mapping '"  -            << opt_name  -            << "' not found! Ignoring."  -            << llendl; +        // This isn't anything a user can affect -- it's a misconfiguration on +        // the part of the coder. Rub the coder's nose in the problem right +        // away so even preliminary testing will surface it. +        llerrs << "Command Line option --" << option +               << " maps to unknown setting!" << llendl;      }  } +} // anonymous namespace  void LLControlGroupCLP::configure(const std::string& config_filename, LLControlGroup* controlGroup)  { @@ -561,11 +671,37 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG              }              boost::function1<void, const token_vector_t&> callback; -            if(option_params.has("map-to") && (NULL != controlGroup)) +            if (! option_params.has("map-to")) +            { +                // If this option isn't mapped to a settings variable, is it +                // one of the ones for which that's unreasonable, or did +                // someone carelessly add a new option? (Make all these +                // configuration errors fatal so a maintainer will catch them +                // right away.) +                std::set<std::string>::const_iterator found = unmapped_options.find(long_name); +                if (found == unmapped_options.end()) +                { +                    llerrs << "New command-line option " << long_name +                           << " should map-to a variable in settings.xml" << llendl; +                } +            } +            else                    // option specifies map-to              {                  std::string controlName = option_params["map-to"].asString(); -                callback = boost::bind(setControlValueCB, _1,  -                                       controlName, controlGroup); +                if (! controlGroup) +                { +                    llerrs << "Must pass gSavedSettings to LLControlGroupCLP::configure() for " +                           << long_name << " (map-to " << controlName << ")" << llendl; +                } + +                LLControlVariable* ctrl = controlGroup->getControl(controlName); +                if (! ctrl) +                { +                    llerrs << "Option " << long_name << " specifies map-to " << controlName +                           << " which does not exist" << llendl; +                } + +                callback = boost::bind(setControlValueCB, _1, long_name, ctrl);              }              this->addOptionDesc( diff --git a/indra/newview/llcommandlineparser.h b/indra/newview/llcommandlineparser.h index 44f2a26843..71388b8217 100755 --- a/indra/newview/llcommandlineparser.h +++ b/indra/newview/llcommandlineparser.h @@ -86,7 +86,7 @@ public:  	 *   	 * Use this to handle the results of parsing.   	 */ -	void notify(); +	bool notify();  	/** @brief Print a description of the configured options.  	 * diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ddb9d3bc43..9d292ce7bb 100755 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -30,6 +30,7 @@  #include <fstream>  #include <boost/regex.hpp> +#include <boost/assign/list_of.hpp>  #include "llfeaturemanager.h"  #include "lldir.h" @@ -52,6 +53,8 @@  #include "llboost.h"  #include "llweb.h"  #include "llviewershadermgr.h" +#include "llstring.h" +#include "stringize.h"  #if LL_WINDOWS  #include "lldxhardware.h" @@ -187,6 +190,55 @@ void LLFeatureList::dump()  	LL_DEBUGS("RenderInit") << LL_ENDL;  } +static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of +	("Low") +	("LowMid") +	("Mid") +	("MidHigh") +	("High") +	("HighUltra") +	("Ultra") +; + +U32 LLFeatureManager::getMaxGraphicsLevel() const +{ +	return sGraphicsLevelNames.size() - 1; +} + +bool LLFeatureManager::isValidGraphicsLevel(U32 level) const +{ +	return (level <= getMaxGraphicsLevel()); +} + +std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const +{ +	if (isValidGraphicsLevel(level)) +	{ +		return sGraphicsLevelNames[level]; +	} +	return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. " +					 << getMaxGraphicsLevel()); +} + +S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const +{ +	const std::string FixedFunction("FixedFunction"); +	std::string rname(name); +	if (LLStringUtil::endsWith(rname, FixedFunction)) +	{ +		// chop off any "FixedFunction" suffix +		rname = rname.substr(0, rname.length() - FixedFunction.length()); +	} +	for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i) +	{ +		if (sGraphicsLevelNames[i] == rname) +		{ +			return i; +		} +	} +	return -1; +} +  LLFeatureList *LLFeatureManager::findMask(const std::string& name)  {  	if (mMaskList.count(name)) @@ -620,7 +672,7 @@ void LLFeatureManager::applyRecommendedSettings()  {  	// apply saved settings  	// cap the level at 2 (high) -	S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); +	U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));  	llinfos << "Applying Recommended Features" << llendl; @@ -696,62 +748,33 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)  	}  } -void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) +void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)  {  	LLViewerShaderMgr::sSkipReload = true;  	applyBaseMasks(); -	 -	switch (level) + +	// if we're passed an invalid level, default to "Low" +	std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low"); +	if (features == "Low")  	{ -		case 0:  #if LL_DARWIN -			// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac -			// systems which support them instead of falling back to fixed-function unnecessarily -			// MAINT-2157 -			// -			if (gGLManager.mGLVersion < 2.1f) -			{ -				maskFeatures("LowFixedFunction");			 -			} -			else -			{ //same as low, but with "Basic Shaders" enabled -				maskFeatures("Low"); -			} +		// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac +		// systems which support them instead of falling back to fixed-function unnecessarily +		// MAINT-2157 +		if (gGLManager.mGLVersion < 2.1f)  #else -			if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel) -			{ //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip -				maskFeatures("LowFixedFunction");			 -			} -			else -			{ //same as low, but with "Basic Shaders" enabled -				maskFeatures("Low"); -			} +		// only use fixed function by default if GL version < 3.0 or this is an intel graphics chip +		if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)  #endif -			break; -		case 1: -			maskFeatures("LowMid"); -			break; -		case 2: -			maskFeatures("Mid"); -			break; -		case 3: -			maskFeatures("MidHigh"); -			break; -		case 4: -			maskFeatures("High"); -			break; -		case 5: -			maskFeatures("HighUltra"); -			break; -		case 6: -			maskFeatures("Ultra"); -			break; -		default: -			maskFeatures("Low"); -			break; +		{ +            // same as Low, but with "Basic Shaders" disabled +			features = "LowFixedFunction"; +		}  	} +	maskFeatures(features); +  	applyFeatures(skipFeatures);  	LLViewerShaderMgr::sSkipReload = false; diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index ad72c16743..3b8d251236 100755 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -134,8 +134,18 @@ public:  	// skipFeatures forces skipping of mostly hardware settings  	// that we don't want to change when we change graphics  	// settings -	void setGraphicsLevel(S32 level, bool skipFeatures); -	 +	void setGraphicsLevel(U32 level, bool skipFeatures); + +	// What 'level' values are valid to pass to setGraphicsLevel()? +	// 0 is the low end... +	U32 getMaxGraphicsLevel() const; +	bool isValidGraphicsLevel(U32 level) const; + +	// setGraphicsLevel() levels have names. +	std::string getNameForGraphicsLevel(U32 level) const; +	// returns -1 for unrecognized name (hence S32 rather than U32) +	S32 getGraphicsLevelForName(const std::string& name) const; +  	void applyBaseMasks();  	void applyRecommendedSettings(); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 83fb887d81..163f294d2a 100755 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -33,8 +33,10 @@  // Viewer includes  #include "llagent.h" +#include "llagentui.h"  #include "llappviewer.h"   #include "llsecondlifeurls.h" +#include "llslurl.h"  #include "llvoiceclient.h"  #include "lluictrlfactory.h"  #include "llviewertexteditor.h" @@ -250,12 +252,16 @@ LLSD LLFloaterAbout::getInfo()  	LLViewerRegion* region = gAgent.getRegion();  	if (region)  	{ -		const LLVector3d &pos = gAgent.getPositionGlobal(); +		LLVector3d pos = gAgent.getPositionGlobal();  		info["POSITION"] = ll_sd_from_vector3d(pos); +		info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));  		info["REGION"] = gAgent.getRegion()->getName();  		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();  		info["HOSTIP"] = gAgent.getRegion()->getHost().getString();  		info["SERVER_VERSION"] = gLastVersionChannel; +		LLSLURL slurl; +		LLAgentUI::buildSLURL(slurl); +		info["SLURL"] = slurl.getSLURLString();  	}  	// CPU diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 56b0c15cb9..38592b3f65 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -125,7 +125,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()  	setTitle(LLTrans::getString("NearbyChatTitle"));  	// obsolete, but may be needed for backward compatibility? -	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); +	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT);  	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))  	{ diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index afbb59e723..744ec4de2b 100755 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -83,7 +83,9 @@  BOOL 				gHackGodmode = FALSE;  #endif - +// Should you contemplate changing the name "Global", please first grep for +// that string literal. There are at least a couple other places in the C++ +// code that assume the LLControlGroup named "Global" is gSavedSettings.  LLControlGroup gSavedSettings("Global");	// saved at end of session  LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session  LLControlGroup gCrashSettings("CrashSettings");	// saved at end of session diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index fc8bc33096..9206690c8f 100755 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -8,7 +8,7 @@  		Bygget med [COMPILER] version [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 4387a61963..5245467183 100755 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -8,7 +8,7 @@  		Kompiliert mit [COMPILER] version [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Sie befinden sich in [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Sie befinden sich in [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 63eb87f27a..703015af20 100755 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -22,7 +22,9 @@ Built with [COMPILER] version [COMPILER_VERSION]  </floater.string>    <floater.string       name="AboutPosition"> -You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +SLURL: <nolink>[SLURL]</nolink> +(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL] diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 3696c7e12c..7ca1e3721f 100755 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -8,7 +8,7 @@  		Compilado con [COMPILER], versión [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Estás en la posición [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index a659cb4245..d45bdccf3e 100755 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -8,7 +8,7 @@  		Compilé avec [COMPILER] version [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Vous êtes à [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index c672511fc5..b0fb585fa2 100755 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -8,7 +8,7 @@  		Generato con [COMPILER] versione [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Tu sei  [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Tu sei  [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 6d5df75645..eae52c98ec 100755 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -8,7 +8,7 @@  		コンパイラー [COMPILER] [COMPILER_VERSION] バージョン  	</floater.string>  	<floater.string name="AboutPosition"> -		あなたの現在地は、[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] の [REGION] です。位置は <nolink>[HOSTNAME]</nolink> です。([HOSTIP]) +		あなたの現在地は、[POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] の [REGION] です。位置は <nolink>[HOSTNAME]</nolink> です。([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml index 409429ffaa..61a72ff27d 100755 --- a/indra/newview/skins/default/xui/pl/floater_about.xml +++ b/indra/newview/skins/default/xui/pl/floater_about.xml @@ -8,7 +8,7 @@  		Buduj z [COMPILER] wersją [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 299f88b22a..d089266342 100755 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -7,7 +7,7 @@  		Construído com [COMPILER] versão [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]</nolink>([HOSTIP]) +		Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em [HOSTNAME]</nolink>([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index bb6266ac9a..2b2b3cf453 100755 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -8,7 +8,7 @@  		Использован компилятор [COMPILER], версия [COMPILER_VERSION]  	</floater.string>  	<floater.string name="AboutPosition"> -		Вы в точке [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index 9cc9c7a220..4dcf6200c6 100755 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -8,7 +8,7 @@  		[COMPILER] [COMPILER_VERSION] sürümü ile oluşturuldu  	</floater.string>  	<floater.string name="AboutPosition"> -		<nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] konumundasınız +		<nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 643881e416..1193243c7e 100755 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -8,7 +8,7 @@  		以 [COMPILER_VERSION] 版本 [COMPILER] 建置  	</floater.string>  	<floater.string name="AboutPosition"> -		你的方位是 [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index 3ba25f3c10..a40b5c9a3d 100755 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -49,10 +49,10 @@ LLControlGroup::~LLControlGroup()  }  // Implementation of just the LLControlGroup methods we requre -BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist) +LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)  {  	test_preferred_maturity = initial_val; -	return true; +	return NULL;  }  void LLControlGroup::setU32(const std::string& name, U32 val) @@ -80,7 +80,7 @@ namespace tut  	void agentaccess_object_t::test<1>()  	{  		LLControlGroup cgr("test"); -		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); +		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);  		LLAgentAccess aa(cgr);  		cgr.setU32("PreferredMaturity", SIM_ACCESS_PG); @@ -109,7 +109,7 @@ namespace tut  	void agentaccess_object_t::test<2>()  	{  		LLControlGroup cgr("test"); -		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); +		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);  		LLAgentAccess aa(cgr);  		// make sure default is PG @@ -157,7 +157,7 @@ namespace tut  	void agentaccess_object_t::test<3>()  	{  		LLControlGroup cgr("test"); -		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); +		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);  		LLAgentAccess aa(cgr);  #ifndef HACKED_GODLIKE_VIEWER @@ -195,7 +195,7 @@ namespace tut  	void agentaccess_object_t::test<4>()  	{  		LLControlGroup cgr("test"); -		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); +		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);  		LLAgentAccess aa(cgr);  #ifndef HACKED_GODLIKE_VIEWER @@ -272,7 +272,7 @@ namespace tut  	void agentaccess_object_t::test<5>()  	{  		LLControlGroup cgr("test"); -		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); +		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);  		LLAgentAccess aa(cgr);  		cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index f038112fd0..272a46aa8d 100755 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -175,8 +175,8 @@ F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }  U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }  void LLControlGroup::setString(const std::string& name, const std::string& val) {}  std::string LLControlGroup::getString(const std::string& name) { return "test_string"; } -BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; } -BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; } +LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; } +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }  #include "lluicolortable.h"  void LLUIColorTable::saveUserSettings(void)const {} @@ -344,13 +344,13 @@ namespace tut  			gTOSReplyPump = 0; // clear the callback. -			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE); -			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE); -			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE); -			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE); -			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE); -			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE); -			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE); +			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO); +			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);  			LLSD authenticator = LLSD::emptyMap();  			LLSD identifier = LLSD::emptyMap(); diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp index 703603e2db..d7e87ed52e 100755 --- a/indra/newview/tests/llsecapi_test.cpp +++ b/indra/newview/tests/llsecapi_test.cpp @@ -39,10 +39,10 @@  LLControlGroup::LLControlGroup(const std::string& name)  : LLInstanceTracker<LLControlGroup, std::string>(name) {}  LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name,                                     const std::string& initial_val,                                     const std::string& comment, -                                   BOOL persist) {return TRUE;} +                                   LLControlVariable::ePersist persist) {return NULL;}  void LLControlGroup::setString(const std::string& name, const std::string& val){}  std::string LLControlGroup::getString(const std::string& name)  { diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index 0235400976..2a8dc15346 100755 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -71,10 +71,10 @@ std::string gLastName;  LLControlGroup::LLControlGroup(const std::string& name)  : LLInstanceTracker<LLControlGroup, std::string>(name) {}  LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name,                                     const std::string& initial_val,                                     const std::string& comment, -                                   BOOL persist) {return TRUE;} +                                   LLControlVariable::ePersist persist) {return NULL;}  void LLControlGroup::setString(const std::string& name, const std::string& val){}  std::string LLControlGroup::getString(const std::string& name)  { diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp index 09343ef227..86229ad636 100755 --- a/indra/newview/tests/llslurl_test.cpp +++ b/indra/newview/tests/llslurl_test.cpp @@ -37,10 +37,10 @@  LLControlGroup::LLControlGroup(const std::string& name)  : LLInstanceTracker<LLControlGroup, std::string>(name) {}  LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name,                                     const std::string& initial_val,                                     const std::string& comment, -                                   BOOL persist) {return TRUE;} +                                   LLControlVariable::ePersist persist) {return NULL;}  void LLControlGroup::setString(const std::string& name, const std::string& val){}  std::string gCmdLineLoginURI; diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp index 710881d811..f6456a2839 100755 --- a/indra/newview/tests/llviewerhelputil_test.cpp +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -49,10 +49,10 @@ static std::string gOS;  LLControlGroup::LLControlGroup(const std::string& name)  	: LLInstanceTracker<LLControlGroup, std::string>(name) {}  LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name,  				   const std::string& initial_val,  				   const std::string& comment, -				   BOOL persist) {return TRUE;} +				   LLControlVariable::ePersist persist) {return NULL;}  void LLControlGroup::setString(const std::string& name, const std::string& val){}  std::string LLControlGroup::getString(const std::string& name)  { diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index a1e97ea17e..06de1cbfa2 100755 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -37,10 +37,10 @@  LLControlGroup::LLControlGroup(const std::string& name)  : LLInstanceTracker<LLControlGroup, std::string>(name) {}  LLControlGroup::~LLControlGroup() {} -BOOL LLControlGroup::declareString(const std::string& name, +LLControlVariable* LLControlGroup::declareString(const std::string& name,                                     const std::string& initial_val,                                     const std::string& comment, -                                   BOOL persist) {return TRUE;} +                                   LLControlVariable::ePersist persist) {return NULL;}  void LLControlGroup::setString(const std::string& name, const std::string& val){}  std::string gCmdLineLoginURI; diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp index 711c2a3d51..20f913b670 100755 --- a/indra/newview/tests/llxmlrpclistener_test.cpp +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -62,8 +62,8 @@ namespace tut              // These variables are required by machinery used by              // LLXMLRPCTransaction. The values reflect reality for this test              // executable; hopefully these values are correct. -            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist -            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist +            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist +            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist          }          // LLEventPump listener signature diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 5e08e54b7c..19863dd845 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -34,9 +34,15 @@ import tarfile  import time  import random  viewer_dir = os.path.dirname(__file__) -# add llmanifest library to our path so we don't have to muck with PYTHONPATH -sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util')) -from llmanifest import LLManifest, main, proper_windows_path, path_ancestors +# Add indra/lib/python to our path so we don't have to muck with PYTHONPATH. +# Put it FIRST because some of our build hosts have an ancient install of +# indra.util.llmanifest under their system Python! +sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python")) +from indra.util.llmanifest import LLManifest, main, proper_windows_path, path_ancestors +try: +    from llbase import llsd +except ImportError: +    from indra.base import llsd  class ViewerManifest(LLManifest):      def is_packaging_viewer(self): @@ -65,13 +71,13 @@ class ViewerManifest(LLManifest):                  # include the entire shaders directory recursively                  self.path("shaders")                  # include the extracted list of contributors -                contributor_names = self.extract_names("../../doc/contributions.txt") -                self.put_in_file(contributor_names, "contributors.txt") -                self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")]) +                contributions_path = "../../doc/contributions.txt" +                contributor_names = self.extract_names(contributions_path) +                self.put_in_file(contributor_names, "contributors.txt", src=contributions_path)                  # include the extracted list of translators -                translator_names = self.extract_names("../../doc/translations.txt") -                self.put_in_file(translator_names, "translators.txt") -                self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")]) +                translations_path = "../../doc/translations.txt" +                translator_names = self.extract_names(translations_path) +                self.put_in_file(translator_names, "translators.txt", src=translations_path)                  # include the list of Lindens (if any)                  #   see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits                  linden_names_path = os.getenv("LINDEN_CREDITS") @@ -85,10 +91,9 @@ class ViewerManifest(LLManifest):                      else:                           # all names should be one line, but the join below also converts to a string                          linden_names = ', '.join(linden_file.readlines()) -                        self.put_in_file(linden_names, "lindens.txt") +                        self.put_in_file(linden_names, "lindens.txt", src=linden_names_path)                          linden_file.close()                          print "Linden names extracted from '%s'" % linden_names_path -                        self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])                  # ... and the entire windlight directory                  self.path("windlight") @@ -99,6 +104,27 @@ class ViewerManifest(LLManifest):                      self.path("dictionaries")                      self.end_prefix(pkgdir) +                # CHOP-955: If we have "sourceid" in the build process +                # environment, generate it into settings_install.xml. +                try: +                    sourceid = os.environ["sourceid"] +                except KeyError: +                    # no sourceid, no settings_install.xml file +                    pass +                else: +                    if sourceid: +                        # Single-entry subset of the LLSD content of settings.xml +                        content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers', +                                                     Persist=1, +                                                     Type='String', +                                                     Value=sourceid)) +                        # put_in_file(src=) need not be an actual pathname; it +                        # only needs to be non-empty +                        settings_install = self.put_in_file(llsd.format_pretty_xml(content), +                                                            "settings_install.xml", +                                                            src="environment") +                        print "Put sourceid '%s' in %s" % (sourceid, settings_install) +                  self.end_prefix("app_settings")              if self.prefix(src="character"): @@ -196,24 +222,26 @@ class ViewerManifest(LLManifest):          """ Convenience function that returns the command-line flags          for the grid""" -        # Set command line flags relating to the target grid -        grid_flags = '' -        if not self.default_grid(): -            grid_flags = "--grid %(grid)s "\ -                         "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\ -                           {'grid':self.grid()} - -        # Deal with settings  -        setting_flags = '' -        if not self.default_channel() or not self.default_grid(): -            if self.default_grid(): -                setting_flags = '--settings settings_%s.xml'\ -                                % self.channel_lowerword() -            else: -                setting_flags = '--settings settings_%s_%s.xml'\ -                                % (self.grid(), self.channel_lowerword()) -                                                 -        return " ".join((grid_flags, setting_flags)).strip() +        # The original role of this method seems to have been to build a +        # grid-specific viewer: one that would, on launch, preselect a +        # particular grid. (Apparently that dates back to when the protocol +        # between viewer and simulator required them to be updated in +        # lockstep, so that "the beta grid" required "a beta viewer.") But +        # those viewer command-line switches no longer work without tweaking +        # user_settings/grids.xml. In fact, going forward, it's unclear what +        # use case that would address. + +        # This method also set a channel-specific (or grid-and-channel- +        # specific) user_settings/settings_something.xml file. It has become +        # clear that saving user settings in a channel-specific file causes +        # more problems (confusion) than it solves, so we've discontinued that. + +        # In fact we now avoid forcing viewer command-line switches at all, +        # instead introducing a settings_install.xml file. Command-line +        # switches don't aggregate well; for instance the generated --channel +        # switch actually prevented the user specifying --channel on the +        # command line. Settings files have well-defined override semantics. +        return None      def extract_names(self,src):          try: @@ -530,8 +558,7 @@ class WindowsManifest(ViewerManifest):              'final_exe' : self.final_exe(),              'grid':self.args['grid'],              'grid_caps':self.args['grid'].upper(), -            # escape quotes becase NSIS doesn't handle them well -            'flags':self.flags_list().replace('"', '$\\"'), +            'flags':'',              'channel':self.channel(),              'channel_oneword':self.channel_oneword(),              'channel_unique':self.channel_unique(), @@ -759,9 +786,6 @@ class DarwinManifest(ViewerManifest):                      self.end_prefix("llplugin") -                # command line arguments for connecting to the proper grid -                self.put_in_file(self.flags_list(), 'arguments.txt') -                  self.end_prefix("Resources")              self.end_prefix("Contents") @@ -807,10 +831,6 @@ class DarwinManifest(ViewerManifest):                                   'bundle': self.get_dst_prefix()                  }) -        channel_standin = 'Second Life Viewer'  # hah, our default channel is not usable on its own -        if not self.default_channel(): -            channel_standin = self.channel() -          imagename="SecondLife_" + '_'.join(self.args['version'])          # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning. @@ -928,9 +948,6 @@ class LinuxManifest(ViewerManifest):              self.path("install.sh")              self.end_prefix("linux_tools") -        # Create an appropriate gridargs.dat for this package, denoting required grid. -        self.put_in_file(self.flags_list(), 'etc/gridargs.dat') -          if self.prefix(src="", dst="bin"):              self.path("secondlife-bin","do-not-directly-run-secondlife-bin")              self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") | 
