diff --git a/src/settings.cpp b/src/settings.cpp index 4e8c08b09c..25dc2600e4 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -613,6 +613,20 @@ const std::string &StringSettingDesc::Read(const void *object) const return *reinterpret_cast(GetVariableAddress(object, this->save)); } +static const char *GetSettingConfigName(const SettingDesc &sd) +{ + const char *name = sd.name; + if (sd.guiproc != nullptr) { + SettingOnGuiCtrlData data; + data.type = SOGCT_CFG_NAME; + data.str = name; + if (sd.guiproc(data)) { + name = data.str; + } + } + return name; +} + /** * Load values from a group of an IniFile structure into the internal representation * @param ini pointer to IniFile structure that holds administrative information @@ -635,7 +649,7 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co item = nullptr; } else { /* For settings.xx.yy load the settings from [xx] yy = ? */ - std::string s{ sd->name }; + std::string s{ GetSettingConfigName(*sd) }; auto sc = s.find('.'); if (sc != std::string::npos) { group = ini.GetGroup(s.substr(0, sc)); @@ -656,6 +670,13 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co sc = s.find('.'); if (sc != std::string::npos) item = ini.GetGroup(s.substr(0, sc))->GetItem(s.substr(sc + 1), false); } + if (item == nullptr && sd->guiproc != nullptr) { + SettingOnGuiCtrlData data; + data.type = SOGCT_CFG_FALLBACK_NAME; + if (sd->guiproc(data)) { + item = group->GetItem(data.str, false); + } + } } sd->ParseValue(item, object); @@ -719,7 +740,7 @@ static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, co if (sd->flags & SF_NO_NEWGAME) continue; /* XXX - wtf is this?? (group override?) */ - std::string s{ sd->name }; + std::string s{ GetSettingConfigName(*sd) }; auto sc = s.find('.'); if (sc != std::string::npos) { group = ini.GetGroup(s.substr(0, sc)); @@ -2209,7 +2230,7 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table) { for (auto &sd : table) { /* For settings.xx.yy load the settings from [xx] yy = ? */ - std::string s{ sd->name }; + std::string s{ GetSettingConfigName(*sd) }; auto sc = s.find('.'); if (sc == std::string::npos) continue; diff --git a/src/settings_internal.h b/src/settings_internal.h index b1179f2c86..5ed6367896 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -77,12 +77,15 @@ enum SettingType { enum SettingOnGuiCtrlType { SOGCT_DESCRIPTION_TEXT, ///< Description text callback SOGCT_GUI_DROPDOWN_ORDER, ///< SF_GUI_DROPDOWN reordering callback + SOGCT_CFG_NAME, ///< Config file name override + SOGCT_CFG_FALLBACK_NAME, ///< Config file name within group fallback }; struct SettingOnGuiCtrlData { SettingOnGuiCtrlType type; StringID text; int val; + const char *str = nullptr; }; struct IniItem;