Ticket #3737: optionsReset.patch

File optionsReset.patch, 14.1 KB (added by mimo, 8 years ago)
  • binaries/data/mods/public/gui/options/options.js

     
    128128                if (checked === undefined || revert)
    129129                    checked = Engine.ConfigDB_GetValue("user", keyConfig) === "true";
    130130                else if ((Engine.ConfigDB_GetValue("user", keyConfig) === "true") !== checked)
     131                {
    131132                    Engine.ConfigDB_CreateValue("user", keyConfig, String(checked));
     133                    updateStatus();
     134                }
    132135                break;
    133136            case "renderer":
    134137                keyRenderer = option[2].renderer;
     
    156159                    Engine.ConfigDB_CreateValue("user", keyConfig, String(this.checked));
    157160                if (functionBody)
    158161                    eval(functionBody);
    159                 updateStatus(true);
     162                updateStatus();
    160163            };
    161164        }(keyRenderer, keyConfig, functionBody);
    162165
     
    214217                Engine.ConfigDB_CreateValue("user", key, this.caption);
    215218                if (functionBody)
    216219                    eval(functionBody);
    217                 updateStatus(true);
     220                updateStatus();
    218221            };
    219222        }(key, functionBody, minval, maxval);
    220223
     
    233236    return control;
    234237}
    235238
    236 function updateStatus(val)
     239function updateStatus()
    237240{
    238     if (typeof val == "boolean")
    239         Engine.ConfigDB_CreateValue("user", "nosave.haschanges", String(val));
    240     else
    241         val = Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true";
    242 
    243     Engine.GetGUIObjectByName("loadOptions").enabled = val;
    244     Engine.GetGUIObjectByName("saveOptions").enabled = val;
     241    let val = Engine.ConfigDB_HasChanges("user");
     242    Engine.GetGUIObjectByName("revertChanges").enabled = val;
     243    Engine.GetGUIObjectByName("saveChanges").enabled = val;
    245244}
    246245
    247246/**
     
    253252        control.onPress();
    254253}
    255254
     255function resetChanges()
     256{
     257    let btCaptions = [translate("No"), translate("Yes")];
     258    let btCode = [null, function(){ reallyResetChanges(); }];
     259    messageBox(500, 200, translate("Resetting the options needs to close the game. Are you sure you want to continue ?"),
     260        translate("Warning"), 0, btCaptions, btCode);
     261}
     262
     263function reallyResetChanges()
     264{
     265    for (let category in options)
     266        for (let setting of options[category])
     267            if (setting[2].config)
     268                Engine.ConfigDB_RemoveValue("user", setting[2].config);
     269
     270    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
     271    Engine.Exit();
     272}
     273
    256274function revertChanges()
    257275{
    258276    Engine.ConfigDB_Reload("user");
    259     updateStatus(false);
     277    updateStatus();
    260278    init({ "revert": true });
    261279}
    262280
     
    264282{
    265283    registerChanges();
    266284    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
    267     updateStatus(false);
     285    updateStatus();
    268286}
    269287
    270288/**
     
    273291function closePage()
    274292{
    275293    registerChanges();
    276     if (Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true")
     294    if (Engine.ConfigDB_HasChanges("user"))
    277295    {
    278296        let btCaptions = [translate("No"), translate("Yes")];
    279297        let btCode = [null, function(){ closePageWithoutConfirmation(); }];
  • binaries/data/mods/public/gui/options/options.xml

     
    6565                </object>
    6666            </repeat>
    6767        </object>
    68         <object name="loadOptions" type="button" style="ModernButtonRed" size="50%-170 100%-44 50%-70 100%-16" hotkey="cancel">
     68        <object type="button" style="ModernButtonRed" size="50%-236 100%-44 50%-136 100%-16" hotkey="cancel">
     69            <translatableAttribute id="caption">Reset</translatableAttribute>
     70            <translatableAttribute id="tooltip">Reset all user settings (will close the game)</translatableAttribute>
     71            <action on="Press">resetChanges();</action>
     72        </object>
     73        <object name="revertChanges" type="button" style="ModernButtonRed" size="50%-104 100%-44 50%-4 100%-16" hotkey="cancel">
    6974            <translatableAttribute id="caption">Revert</translatableAttribute>
    7075            <translatableAttribute id="tooltip">Revert to previous saved settings</translatableAttribute>
    7176            <action on="Press">revertChanges();</action>
    7277        </object>
    73         <object name="saveOptions" type="button" style="ModernButtonRed" size="50%-62 100%-44 50%+38 100%-16">
     78        <object name="saveChanges" type="button" style="ModernButtonRed" size="50%+4 100%-44 50%+104 100%-16">
    7479            <translatableAttribute id="caption">Save</translatableAttribute>
    7580            <translatableAttribute id="tooltip">Save changes</translatableAttribute>
    7681            <action on="Press">saveChanges();</action>
    7782        </object>
    78         <object type="button" style="ModernButtonRed" size="50%+70 100%-44 50%+170 100%-16">
     83        <object type="button" style="ModernButtonRed" size="50%+136 100%-44 50%+236 100%-16">
    7984            <translatableAttribute id="caption">Quit</translatableAttribute>
    8085            <translatableAttribute id="tooltip">Unsaved changes affect this session only</translatableAttribute>
    8186            <action on="Press">closePage();</action>
  • binaries/data/mods/public/gui/splashscreen/splashscreen.xml

     
    2727        <object name="btnOK" type="button" style="ModernButtonRed" size="18 100%-45 50%-5 100%-17" hotkey="cancel">
    2828            <translatableAttribute id="caption">OK</translatableAttribute>
    2929            <action on="Press"><![CDATA[
    30             if (Engine.GetGUIObjectByName("displaySplashScreen").checked)
    31                 Engine.ConfigDB_CreateValue("user", "splashscreenversion", 0);
    32             else
    33                 Engine.ConfigDB_CreateValue("user", "splashscreenversion", Engine.GetFileMTime("gui/splashscreen/splashscreen.txt"));
    34             Engine.ConfigDB_WriteFile("user", "config/user.cfg");
     30            let value = Engine.GetGUIObjectByName("displaySplashScreen").checked ? 0 : Engine.GetFileMTime("gui/splashscreen/splashscreen.txt");
     31            Engine.ConfigDB_CreateValueAndWriteFile("user", "splashscreenversion", value, "config/user.cfg");
    3532            Engine.PopGuiPageCB();
    3633            ]]></action>
    3734        </object>
  • source/ps/ConfigDB.cpp

     
    2929typedef std::map<CStr, CConfigValueSet> TConfigMap;
    3030TConfigMap CConfigDB::m_Map[CFG_LAST];
    3131VfsPath CConfigDB::m_ConfigFile[CFG_LAST];
     32bool CConfigDB::m_HasChanges[CFG_LAST];
    3233
    3334static pthread_mutex_t cfgdb_mutex = PTHREAD_MUTEX_INITIALIZER;
    3435
     
    114115GETVAL(std::string)
    115116#undef GETVAL
    116117
     118bool CConfigDB::HasChanges(EConfigNamespace ns) const
     119{
     120    CHECK_NS(false);
     121
     122    CScopeLock s(&cfgdb_mutex);
     123    return m_HasChanges[ns];
     124}
     125
    117126void CConfigDB::GetValues(EConfigNamespace ns, const CStr& name, CConfigValueSet& values) const
    118127{
    119128    CHECK_NS(;);
     
    187196        it = m_Map[ns].insert(m_Map[ns].begin(), make_pair(name, CConfigValueSet(1)));
    188197
    189198    it->second[0] = value;
     199    m_HasChanges[ns] = true;
    190200}
    191201
     202void CConfigDB::RemoveValue(EConfigNamespace ns, const CStr& name)
     203{
     204    CHECK_NS(;);
     205
     206    CScopeLock s(&cfgdb_mutex);
     207    TConfigMap::iterator it = m_Map[ns].find(name);
     208    if (it == m_Map[ns].end())
     209        return;
     210    m_Map[ns].erase(it);
     211    m_HasChanges[ns] = true;
     212}
     213
    192214void CConfigDB::SetConfigFile(EConfigNamespace ns, const VfsPath& path)
    193215{
    194216    CHECK_NS(;);
     
    357379
    358380    m_Map[ns].swap(newMap);
    359381
     382    m_HasChanges[ns] = false;
    360383    return true;
    361384}
    362385
     
    378401    char* pos = (char*)buf.get();
    379402    for (const std::pair<CStr, CConfigValueSet>& p : m_Map[ns])
    380403    {
    381         if (boost::algorithm::starts_with(p.first, "nosave."))
    382             continue;
    383404        size_t i;
    384405        pos += sprintf(pos, "%s = ", p.first.c_str());
    385406        for (i = 0; i < p.second.size() - 1; ++i)
     
    395416        return false;
    396417    }
    397418
     419    m_HasChanges[ns] = false;
    398420    return true;
    399421}
    400422
     423bool CConfigDB::SetValueAndWriteFile(EConfigNamespace ns, const CStr& name, const CStr& value, const VfsPath& path)
     424{
     425    CHECK_NS(false);
     426
     427    CScopeLock s(&cfgdb_mutex);
     428    bool changed = m_HasChanges[ns];
     429
     430    // if there are no previous changes, we can just set the value and then write to file
     431    if (!changed)
     432    {
     433        SetValueString(ns, name, value);
     434        bool ret = WriteFile(ns, path);
     435        m_HasChanges[ns] = !ret;
     436        return ret;
     437    }
     438
     439    // otherwise we set this value in the specified namespace
     440    SetValueString(ns, name, value);
     441    TConfigMap newMap;
     442        m_Map[ns].swap(newMap);
     443    if (!Reload(ns))
     444    {
     445        m_Map[ns].swap(newMap);
     446        m_HasChanges[ns] = true;
     447        return false;
     448    }
     449    // and add it to be written on file
     450    SetValueString(ns, name, value);
     451        bool ret = WriteFile(ns, path);
     452        m_Map[ns].swap(newMap);
     453    m_HasChanges[ns] = changed || !ret;
     454        return ret;
     455}
     456
    401457#undef CHECK_NS
  • source/ps/ConfigDB.h

     
    5252{
    5353    static std::map<CStr, CConfigValueSet> m_Map[];
    5454    static VfsPath m_ConfigFile[];
     55    static bool m_HasChanges[];
    5556
    5657public:
    5758    CConfigDB();
     
    7273    void GetValue(EConfigNamespace ns, const CStr& name, std::string& value);
    7374
    7475    /**
     76     * Returns true if changed with respect to last write on file
     77     */
     78    bool HasChanges(EConfigNamespace ns) const;
     79
     80    /**
    7581     * Attempt to retrieve a vector of values corresponding to the given setting;
    7682     * will search CFG_COMMAND first, and then all namespaces from the specified
    7783     * namespace down.
     
    96102     * existed the value is replaced.
    97103     */
    98104    void SetValueString(EConfigNamespace ns, const CStr& name, const CStr& value);
     105
     106    /**
     107     * Remove a config value in the specified namespace.
     108     */
     109    void RemoveValue(EConfigNamespace ns, const CStr& name);
    99110   
    100111    /**
    101112     * Set the path to the config file used to populate the specified namespace
     
    135146     *  false:  if an error occurred
    136147     */
    137148    bool WriteFile(EConfigNamespace ns) const;
     149
     150    /**
     151     * Save a config value in the specified namespace (if the config variable
     152     * existed the value is replaced) and write it to file.
     153     *
     154     * Returns:
     155     *  true:   if the config value was successfully saved and written to the file
     156     *  false:  if an error occurred
     157     */
     158    bool SetValueAndWriteFile(EConfigNamespace ns, const CStr& name, const CStr& value, const VfsPath& path);
    138159};
    139160
    140161
  • source/ps/scripting/JSInterface_ConfigDB.cpp

     
    4242    return true;
    4343}
    4444
     45bool JSI_ConfigDB::HasChanges(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString)
     46{
     47    EConfigNamespace cfgNs;
     48    if (!GetConfigNamespace(cfgNsString, cfgNs))
     49        return false;
     50
     51    return g_ConfigDB.HasChanges(cfgNs);
     52}
     53
    4554std::string JSI_ConfigDB::GetValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, std::string name)
    4655{
    4756    EConfigNamespace cfgNs;
     
    6372    return true;
    6473}
    6574
     75bool JSI_ConfigDB::RemoveValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, std::string name)
     76{
     77    EConfigNamespace cfgNs;
     78    if (!GetConfigNamespace(cfgNsString, cfgNs))
     79        return false;
     80
     81    g_ConfigDB.RemoveValue(cfgNs, name);
     82    return true;
     83}
     84
    6685bool JSI_ConfigDB::WriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, Path path)
    6786{
    6887    EConfigNamespace cfgNs;
     
    7392    return ret;
    7493}
    7594
     95bool JSI_ConfigDB::CreateValueAndWriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString,  std::string name, std::string value, Path path)
     96{
     97    EConfigNamespace cfgNs;
     98    if (!GetConfigNamespace(cfgNsString, cfgNs))
     99        return false;
     100
     101    bool ret = g_ConfigDB.SetValueAndWriteFile(cfgNs, name, value, path);
     102    return ret;
     103}
     104
    76105bool JSI_ConfigDB::Reload(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString)
    77106{
    78107    EConfigNamespace cfgNs;
     
    95124
    96125void JSI_ConfigDB::RegisterScriptFunctions(ScriptInterface& scriptInterface)
    97126{
     127    scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::HasChanges>("ConfigDB_HasChanges");
    98128    scriptInterface.RegisterFunction<std::string, std::wstring, std::string, &JSI_ConfigDB::GetValue>("ConfigDB_GetValue");
    99129    scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, &JSI_ConfigDB::CreateValue>("ConfigDB_CreateValue");
     130    scriptInterface.RegisterFunction<bool, std::wstring, std::string, &JSI_ConfigDB::RemoveValue>("ConfigDB_RemoveValue");
    100131    scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::WriteFile>("ConfigDB_WriteFile");
     132    scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, Path, &JSI_ConfigDB::CreateValueAndWriteFile>("ConfigDB_CreateValueAndWriteFile");
    101133    scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::SetFile>("ConfigDB_SetFile");
    102134    scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::Reload>("ConfigDB_Reload");
    103135   
  • source/ps/scripting/JSInterface_ConfigDB.h

     
    2424namespace JSI_ConfigDB
    2525{
    2626    bool GetConfigNamespace(std::wstring cfgNsString, EConfigNamespace& cfgNs);
     27    bool HasChanges(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString);
    2728    std::string GetValue(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name);
    2829    bool CreateValue(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name, std::string value);
     30    bool RemoveValue(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name);
    2931    bool WriteFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, Path path);
     32    bool CreateValueAndWriteFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name, std::string value, Path path);
    3033    bool Reload(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString);
    3134    bool SetFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, Path path);
    3235    void RegisterScriptFunctions(ScriptInterface& scriptInterface);