diff options
| -rw-r--r-- | indra/newview/lldaycyclemanager.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/lldaycyclemanager.h | 3 | ||||
| -rw-r--r-- | indra/newview/llfloaterdeleteenvpreset.cpp | 51 | ||||
| -rw-r--r-- | indra/newview/llfloaterdeleteenvpreset.h | 4 | ||||
| -rw-r--r-- | indra/newview/llfloatereditdaycycle.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llfloatereditdaycycle.h | 1 | ||||
| -rw-r--r-- | indra/newview/llfloatereditsky.cpp | 22 | ||||
| -rw-r--r-- | indra/newview/llfloatereditsky.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterenvironmentsettings.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llfloaterenvironmentsettings.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llfloaterregioninfo.h | 2 | ||||
| -rw-r--r-- | indra/newview/llwldaycycle.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llwldaycycle.h | 5 | ||||
| -rw-r--r-- | indra/newview/llwlparammanager.cpp | 46 | ||||
| -rw-r--r-- | indra/newview/llwlparammanager.h | 7 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_delete_env_preset.xml | 12 | 
17 files changed, 148 insertions, 62 deletions
| diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index 07a9a72e68..ab442d7c83 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -109,6 +109,22 @@ bool LLDayCycleManager::deletePreset(const std::string& name)  	return true;  } +bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const +{ +	// We're traversing local day cycles, they can only reference local skies. +	LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL); + +	for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it) +	{ +		if (it->second.hasReferencesTo(key)) +		{ +			return true; +		} +	} + +	return false; +} +  boost::signals2::connection LLDayCycleManager::setModifyCallback(const modify_signal_t::slot_type& cb)  {  	return mModifySignal.connect(cb); diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h index 0d4a474ac6..032e336491 100644 --- a/indra/newview/lldaycyclemanager.h +++ b/indra/newview/lldaycyclemanager.h @@ -54,6 +54,9 @@ public:  	bool savePreset(const std::string& name, const LLSD& data);  	bool deletePreset(const std::string& name); +	/// @return true if there is a day cycle that refers to the sky preset. +	bool isSkyPresetReferenced(const std::string& preset_name) const; +  	/// Emitted when a preset gets added or deleted.  	boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb); diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp index 74c837af53..b78e124e07 100644 --- a/indra/newview/llfloaterdeleteenvpreset.cpp +++ b/indra/newview/llfloaterdeleteenvpreset.cpp @@ -62,7 +62,9 @@ BOOL LLFloaterDeleteEnvPreset::postBuild()  	getChild<LLButton>("delete")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnDelete, this));  	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnCancel, this)); -	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::onDayCycleListChange, this)); +	// Listen to presets addition/removal. +	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateDayCyclesList, this)); +	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateSkyPresetsList, this));  	return TRUE;  } @@ -113,6 +115,13 @@ void LLFloaterDeleteEnvPreset::onBtnDelete()  	}  	else if (param == "sky")  	{ +		// Don't allow deleting presets referenced by local day cycles. +		if (LLDayCycleManager::instance().isSkyPresetReferenced(preset_name)) +		{ +			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", getString("msg_sky_is_referenced"))); +			return; +		} +  		LLWLParamManager& wl_mgr = LLWLParamManager::instance();  		// Don't allow deleting system presets. @@ -155,6 +164,8 @@ void LLFloaterDeleteEnvPreset::onBtnCancel()  void LLFloaterDeleteEnvPreset::populateWaterPresetsList()  { +	if (mKey.asString() != "water") return; +  	mPresetCombo->removeall();  	// *TODO: Reload the list when user preferences change. @@ -168,10 +179,14 @@ void LLFloaterDeleteEnvPreset::populateWaterPresetsList()  		bool enabled = (name != water_mgr.mCurParams.mName); // don't allow deleting current preset  		mPresetCombo->add(name, ADD_BOTTOM, enabled);  	} + +	postPopulate();  }  void LLFloaterDeleteEnvPreset::populateSkyPresetsList()  { +	if (mKey.asString() != "sky") return; +  	mPresetCombo->removeall();  	std::string cur_preset; @@ -187,14 +202,24 @@ void LLFloaterDeleteEnvPreset::populateSkyPresetsList()  	for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = sky_params_map.begin(); it != sky_params_map.end(); it++)  	{  		const LLWLParamKey& key = it->first; -		if (key.scope == LLEnvKey::SCOPE_REGION) continue; // list only local presets -		bool enabled = key.name != cur_preset && !sky_mgr.isSystemPreset(key.name); + +		// list only local user presets +		if (key.scope == LLEnvKey::SCOPE_REGION || sky_mgr.isSystemPreset(key.name)) +		{ +			continue; +		} + +		bool enabled = (key.name != cur_preset);  		mPresetCombo->add(key.name, ADD_BOTTOM, enabled);  	} + +	postPopulate();  }  void LLFloaterDeleteEnvPreset::populateDayCyclesList()  { +	if (mKey.asString() != "day_cycle") return; +  	mPresetCombo->removeall();  	// *TODO: Disable current day cycle. @@ -203,6 +228,21 @@ void LLFloaterDeleteEnvPreset::populateDayCyclesList()  	{  		mPresetCombo->add(it->first);  	} + +	postPopulate(); +} + +void LLFloaterDeleteEnvPreset::postPopulate() +{ +	// Handle empty list. +	S32 n_items = mPresetCombo->getItemCount(); + +	if (n_items == 0) +	{ +		mPresetCombo->setLabel(getString("combo_label")); +	} + +	getChild<LLButton>("delete")->setEnabled(n_items > 0);  }  void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation() @@ -215,8 +255,3 @@ void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation()  	LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL);  	LLWLParamManager::instance().removeParamSet(key, true);  } - -void LLFloaterDeleteEnvPreset::onDayCycleListChange() -{ -	populateDayCyclesList(); -} diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloaterdeleteenvpreset.h index 26e3b0728e..63f80d89d8 100644 --- a/indra/newview/llfloaterdeleteenvpreset.h +++ b/indra/newview/llfloaterdeleteenvpreset.h @@ -49,11 +49,11 @@ private:  	void populateSkyPresetsList();  	void populateDayCyclesList(); +	void postPopulate(); +  	void onDeleteDayCycleConfirmation();  	void onDeleteSkyPresetConfirmation(); -	void onDayCycleListChange(); -  	LLComboBox* mPresetCombo;  }; diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp index f6bd4ad6b9..257644d80c 100644 --- a/indra/newview/llfloatereditdaycycle.cpp +++ b/indra/newview/llfloatereditdaycycle.cpp @@ -150,6 +150,9 @@ void LLFloaterEditDayCycle::initCallbacks(void)  	// Connect to day cycle manager events.  	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this)); +	// Connect to sky preset list changes. +	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this)); +  	// Connect to region info updates.  	LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this));  } @@ -794,6 +797,14 @@ void LLFloaterEditDayCycle::onDayCycleListChange()  	}  } +void LLFloaterEditDayCycle::onSkyPresetListChange() +{ +	refreshSkyPresetsList(); + +	// Refresh sliders from the currently visible day cycle. +	loadTrack(); +} +  // static  std::string LLFloaterEditDayCycle::getRegionName()  { diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h index c6137ba432..a27bc69792 100644 --- a/indra/newview/llfloatereditdaycycle.h +++ b/indra/newview/llfloatereditdaycycle.h @@ -105,6 +105,7 @@ private:  	void onSaveConfirmed();  	void onDayCycleListChange(); +	void onSkyPresetListChange();  	static std::string getRegionName(); diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp index 96dfb7a8a9..f78baf2ed5 100644 --- a/indra/newview/llfloatereditsky.cpp +++ b/indra/newview/llfloatereditsky.cpp @@ -131,6 +131,8 @@ void LLFloaterEditSky::initCallbacks(void)  	mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this));  	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this)); +	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this)); +  	//-------------------------------------------------------------------------  	LLWLParamManager& param_mgr = LLWLParamManager::instance(); @@ -806,8 +808,8 @@ void LLFloaterEditSky::onSkyPresetSelected()  	if (!LLWLParamManager::instance().getParamSet(key, sky_params))  	{ -		llwarns << "No sky preset named " << key.toString() << llendl; -		llassert(false); +		// Manually entered string? +		LL_WARNS("Windlight") << "No sky preset named " << key.toString() << LL_ENDL;  		return;  	} @@ -904,3 +906,19 @@ void LLFloaterEditSky::onSaveConfirmed()  	closeFloater();  } + +void LLFloaterEditSky::onSkyPresetListChange() +{ +	LLWLParamKey key = getSelectedSkyPreset(); // preset being edited +	if (!LLWLParamManager::instance().hasParamSet(key)) +	{ +		// Preset we've been editing doesn't exist anymore. Close the floater. +		closeFloater(false); +	} +	else +	{ +		// A new preset has been added. +		// Refresh the presets list, though it may not make sense as the floater is about to be closed. +		refreshSkyPresetsList(); +	} +} diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h index 9a8feb5188..70a90fb5b3 100644 --- a/indra/newview/llfloatereditsky.h +++ b/indra/newview/llfloatereditsky.h @@ -96,6 +96,8 @@ private:  	void onBtnSave();  	void onBtnCancel(); +	void onSkyPresetListChange(); +  	LLLineEditor*	mSkyPresetNameEditor;  	LLComboBox*		mSkyPresetCombo;  	LLCheckBoxCtrl*	mMakeDefaultCheckBox; diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp index 15dba80b61..0ec6d1c6c8 100644 --- a/indra/newview/llfloaterenvironmentsettings.cpp +++ b/indra/newview/llfloaterenvironmentsettings.cpp @@ -76,7 +76,8 @@ BOOL LLFloaterEnvironmentSettings::postBuild()  	setCloseCallback(boost::bind(&LLFloaterEnvironmentSettings::cancel, this)); -	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::onDayCycleListChange, this)); +	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::populateDayCyclePresetsList, this)); +	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateSkyPresetsList, this));  	return TRUE;  } @@ -164,11 +165,6 @@ void LLFloaterEnvironmentSettings::onSelectDayCyclePreset()  	mDirty = true;  } -void LLFloaterEnvironmentSettings::onDayCycleListChange() -{ -	populateDayCyclePresetsList(); -} -  void LLFloaterEnvironmentSettings::onBtnOK()  {  	mDirty = false; diff --git a/indra/newview/llfloaterenvironmentsettings.h b/indra/newview/llfloaterenvironmentsettings.h index 6d29a5d4d5..0953ab4a65 100644 --- a/indra/newview/llfloaterenvironmentsettings.h +++ b/indra/newview/llfloaterenvironmentsettings.h @@ -50,8 +50,6 @@ private:  	void onSelectSkyPreset();  	void onSelectDayCyclePreset(); -	void onDayCycleListChange(); -  	void onBtnOK();  	void onBtnCancel(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ab164e7db0..567183b955 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -3300,7 +3300,8 @@ BOOL LLPanelEnvironmentInfo::postBuild()  	LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingschange, this));  	LLEnvManagerNew::instance().setRegionSettingsAppliedCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingsApplied, this, _1)); -	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::onDayCycleListChange, this)); +	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::populateDayCyclesList, this)); +	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateSkyPresetsList, this));  	return TRUE;  } @@ -3756,8 +3757,3 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok)  		LLEnvManagerNew::instance().requestRegionSettings();  	}  } - -void LLPanelEnvironmentInfo::onDayCycleListChange() -{ -	populateDayCyclesList(); -} diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 4f5222eb34..6075842e76 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -471,8 +471,6 @@ private:  	void onRegionSettingschange();  	void onRegionSettingsApplied(bool ok); -	void onDayCycleListChange(); -  	bool			mEnableEditing;  	LLRadioGroup*	mRegionSettingsRadioGroup; diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index 80001525f8..e646b605a9 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -270,10 +270,10 @@ bool LLWLDayCycle::removeKeyframe(F32 time)  	return false;  } -bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) +bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const  {  	// scroll through till we find the correct value in the map -	std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.begin(); +	std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin();  	for(; mIt != mTimeMap.end(); ++mIt)   	{  		if(frame == mIt->second)  @@ -315,6 +315,12 @@ bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name)  	return false;  } +bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const +{ +	F32 dummy; +	return getKeytime(keyframe, dummy); +} +  void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe)  {  	lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl; diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index 9dbfad294a..c8585564ed 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -106,7 +106,7 @@ public:  	/// get the first key time for a parameter  	/// returns false if not there -	bool getKeytime(LLWLParamKey keyFrame, F32& keyTime); +	bool getKeytime(LLWLParamKey keyFrame, F32& keyTime) const;  	/// get the param set at a given time  	/// returns true if found one @@ -116,6 +116,9 @@ public:  	/// returns true if it found one  	bool getKeyedParamName(F32 time, std::string & name); +	/// @return true if there are references to the given sky +	bool hasReferencesTo(const LLWLParamKey& keyframe) const; +  	/// removes all references to the sky (paramkey)  	/// does nothing if the sky doesn't exist in the day  	void removeReferencesTo(const LLWLParamKey& keyframe); diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 01aed7c0f1..df52f3328f 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -588,6 +588,7 @@ bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param)  		llassert(!key.name.empty());  		// *TODO: validate params  		mParamList[key] = param; +		mPresetListChangeSignal();  		return true;  	} @@ -596,19 +597,9 @@ bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param)  BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param)  { -	// add a new one if not one there already -	std::map<LLWLParamKey, LLWLParamSet>::const_iterator finder = mParamList.find(key); -	if(finder == mParamList.end()) -	{ -		llassert(!key.name.empty()); -		// *TODO: validate params -		mParamList[key].setAll(param); -		return TRUE; -	} -	else -	{ -		return FALSE; -	} +	LLWLParamSet param_set; +	param_set.setAll(param); +	return addParamSet(key, param_set);  }  bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) @@ -652,14 +643,14 @@ bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param)  		return false;  	} -	mParamList[key].setAll(param); - -	return true; +	LLWLParamSet param_set; +	param_set.setAll(param); +	return setParamSet(key, param_set);  }  void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk)  { -	// *TODO: notify interested parties that a sky preset has been removed. +	// *NOTE: Removing a sky preset invalidates day cycles that refer to it.  	if (key.scope == LLEnvKey::SCOPE_REGION)  	{ @@ -669,18 +660,17 @@ void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_  	}  	// remove from param list -	std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); -	if(mIt != mParamList.end())  -	{ -		mParamList.erase(mIt); -	} -	else +	std::map<LLWLParamKey, LLWLParamSet>::iterator it = mParamList.find(key); +	if (it == mParamList.end())  	{ -		LL_WARNS("WindLight") << "Unable to delete key " << key.toString() << "; not found." << LL_ENDL; +		LL_WARNS("WindLight") << "No sky preset named " << key.name << LL_ENDL; +		return;  	} +	mParamList.erase(it);  	mDay.removeReferencesTo(key); +	// remove from file system if requested  	if (delete_from_disk)  	{  		std::string path_name(getUserDir()); @@ -691,6 +681,9 @@ void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_  			LL_WARNS("WindLight") << "Error removing sky preset " << key.name << " from disk" << LL_ENDL;  		}  	} + +	// signal interested parties +	mPresetListChangeSignal();  }  bool LLWLParamManager::isSystemPreset(const std::string& preset_name) @@ -699,6 +692,11 @@ bool LLWLParamManager::isSystemPreset(const std::string& preset_name)  	return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml");  } +boost::signals2::connection LLWLParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb) +{ +	return mPresetListChangeSignal.connect(cb); +} +  // virtual static  void LLWLParamManager::initSingleton()  { diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 06f56851b6..73bf97f392 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -215,7 +215,9 @@ public:  class LLWLParamManager : public LLSingleton<LLWLParamManager>  {  	LOG_CLASS(LLWLParamManager); +  public: +	typedef boost::signals2::signal<void()> preset_list_signal_t;  	/// save the parameter presets to file  	void savePreset(const LLWLParamKey key); @@ -287,6 +289,9 @@ public:  	/// @return true if the preset comes out of the box  	bool isSystemPreset(const std::string& preset_name); +	/// Emitted when a preset gets added or deleted. +	boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb); +  	/// add all skies in LLSD using the given scope  	void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); @@ -370,6 +375,8 @@ private:  	/*virtual*/ void initSingleton();  	LLWLParamManager();  	~LLWLParamManager(); + +	preset_list_signal_t mPresetListChangeSignal;  };  inline F32 LLWLParamManager::getDomeOffset(void) const diff --git a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml index 82a541d40d..b5de4166f6 100644 --- a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml +++ b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml @@ -17,7 +17,10 @@      <string name="label_sky">Preset:</string>      <string name="label_day_cycle">Day cycle:</string> -   <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string> +    <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string> +    <string name="msg_sky_is_referenced">Cannot remove a preset that is referenced by some day cycle(s).</string> + +    <string name="combo_label">-Select a preset-</string>      <text       follows="top|left|right" @@ -36,12 +39,7 @@       left_pad="10"       name="preset_combo"       top_delta="-5" -     width="200"> -        <combo_box.item -         label="-Select a preset-" -         name="item0" -         value="any" /> -    </combo_box> +     width="200"/>      <button       follows="bottom|right"       height="23" | 
