// $Id: EnumSetting.hh 6015 2007-01-27 16:24:58Z m9710797 $ #ifndef ENUMSETTING_HH #define ENUMSETTING_HH #include "SettingPolicy.hh" #include "SettingImpl.hh" #include "TclObject.hh" #include "CommandException.hh" #include "Completer.hh" #include "StringOp.hh" #include #include #include namespace openmsx { template class EnumSettingPolicy : public SettingPolicy { public: typedef std::map Map; void getPossibleValues(std::set& result) const; protected: EnumSettingPolicy(CommandController& commandController, const std::string& name, const Map& map_); virtual ~EnumSettingPolicy(); std::string toString(T value) const; T fromString(const std::string& str) const; virtual void checkSetValue(T& value) const; void tabCompletion(std::vector& tokens) const; std::string getTypeString() const; void additionalInfo(TclObject& result) const; private: std::string name; Map enumMap; }; template class EnumSetting : public SettingImpl > { public: EnumSetting(CommandController& commandController, const std::string& name, const std::string& description, T initialValue, const typename EnumSettingPolicy::Map& map_, Setting::SaveSetting save = Setting::SAVE); }; //------------- template EnumSettingPolicy::EnumSettingPolicy( CommandController& commandController, const std::string& name_, const Map& map_) : SettingPolicy(commandController) , name(name_), enumMap(map_) { } template EnumSettingPolicy::~EnumSettingPolicy() { } template void EnumSettingPolicy::getPossibleValues(std::set& result) const { for (typename Map::const_iterator it = enumMap.begin(); it != enumMap.end(); ++it) { try { T val = it->second; checkSetValue(val); result.insert(it->first); } catch (MSXException& e) { // ignore } } } template std::string EnumSettingPolicy::toString(T value) const { for (typename Map::const_iterator it = enumMap.begin(); it != enumMap.end() ; ++it) { if (it->second == value) { return it->first; } } assert(false); return ""; // avoid warning } template T EnumSettingPolicy::fromString(const std::string& str) const { typename Map::const_iterator it = enumMap.find(str); if (it == enumMap.end()) { throw CommandException("not a valid value: " + str); } return it->second; } template void EnumSettingPolicy::checkSetValue(T& /*value*/) const { } template void EnumSettingPolicy::tabCompletion(std::vector& tokens) const { std::set stringSet; getPossibleValues(stringSet); Completer::completeString(tokens, stringSet, false); // case insensitive } template std::string EnumSettingPolicy::getTypeString() const { return "enumeration"; } template void EnumSettingPolicy::additionalInfo(TclObject& result) const { TclObject valueList(result.getInterpreter()); std::set values; this->getPossibleValues(values); valueList.addListElements(values.begin(), values.end()); result.addListElement(valueList); } template EnumSetting::EnumSetting( CommandController& commandController, const std::string& name, const std::string& description, T initialValue, const typename EnumSettingPolicy::Map& map_, Setting::SaveSetting save) : SettingImpl >( commandController, name, description, initialValue, save, name, map_) { } } // namespace openmsx #endif