diff -r bc3a51394953 -r 4268a5507725 src/config.cpp --- a/src/config.cpp Sat Aug 03 12:31:36 2013 +0300 +++ b/src/config.cpp Tue Aug 06 13:32:07 2013 +0300 @@ -17,171 +17,121 @@ */ #include -#include #include #include +#include #include "common.h" #include "config.h" #include "misc.h" #include "gui.h" +#include "file.h" config* g_configPointers[MAX_CONFIG]; static ushort g_cfgPointerCursor = 0; // ============================================================================= +static QSettings* getSettingsObject() { +#ifdef PORTABLE +# ifdef _WIN32 +# define EXTENSION ".ini" +# else +# define EXTENSION ".cfg" +# endif // _WIN32 + return new QSettings (str (APPNAME).toLower() + EXTENSION, QSettings::IniFormat); +#else + return new QSettings; +#endif // PORTABLE +} + +// ============================================================================= // Load the configuration from file bool config::load() { - print ("config::load: Loading configuration file...\n"); - print ("config::load: Path to configuration is %1\n", filepath()); - - // Locale must be disabled for atof - setlocale (LC_NUMERIC, "C"); - - File f (filepath(), File::Read); - int ln = 0; - - if (!f) - return false; - - // Read the values. - for (str line : f) { - ln++; - - if (line.isEmpty() || line[0] == '#') - continue; // Empty line or comment. - - // Find the equals sign. - int equals = line.indexOf ('='); - - if (equals == -1) { - fprint (stderr, "couldn't find `=` sign in entry `%1`\n", line); - continue; - } - - str entry = line.left (equals); - str valstring = line.right (line.length() - equals - 1); - - // Find the config entry for this. - config* cfg = null; - - for (config* i : g_configPointers) { - if (!i) - break; - - if (entry == i->name) - cfg = i; - } - - if (!cfg) { - fprint (stderr, "unknown config `%1`\n", entry); - continue; - } - - switch (cfg->getType()) { - case Type_int: - static_cast (cfg)->value = valstring.toInt(); - break; - - case Type_str: - static_cast (cfg)->value = valstring; - break; - - case Type_float: - static_cast (cfg)->value = valstring.toFloat(); - break; - - case Type_bool: { - bool& val = static_cast (cfg)->value; - - if (valstring.toUpper() == "TRUE" || valstring == "1") - val = true; - elif (valstring.toUpper() == "FALSE" || valstring == "0") - val = false; - - break; - } - - case Type_keyseq: - static_cast (cfg)->value = keyseq::fromString (valstring); - break; - - default: - break; - } - } - - f.close(); - return true; -} - -extern_cfg (str, io_ldpath); - -// ============================================================================= -// Save the configuration to disk -bool config::save() { - // The function will write floats, disable the locale now so that they - // are written properly. - setlocale (LC_NUMERIC, "C"); - - // If the directory doesn't exist, create it now. - if (QDir (dirpath()).exists() == false) { - fprint (stderr, "Creating config path %1...\n", dirpath()); - - if (!QDir().mkpath (dirpath())) { - critical ("Failed to create the configuration directory. Configuration cannot be saved!\n"); - return false; - } - } - - File f (filepath(), File::Write); - print ("writing cfg to %1\n", filepath()); - - if (!f) { - critical (fmt (QObject::tr ("Cannot save configuration, cannot open %1 for writing: %2\n"), - filepath(), strerror (errno))); - return false; - } - - fprint (f, "# Configuration file for " APPNAME "\n"); - str valstring; + QSettings* settings = getSettingsObject(); + print ("config::load: Loading configuration file from %1...\n", settings->fileName()); for (config* cfg : g_configPointers) { if (!cfg) break; - if (cfg->isDefault()) - continue; - - switch (cfg->getType()) { - case Type_int: - valstring = fmt ("%1", static_cast (cfg)->value); - break; - - case Type_str: - valstring = static_cast (cfg)->value; - break; - - case Type_float: - valstring = fmt ("%1", static_cast (cfg)->value); + cfg->loadFromConfig (settings); + } + + settings->deleteLater(); + return true; +} + +// ============================================================================= +void intconfig::loadFromConfig (const QSettings* cfg) { + QVariant val = cfg->value (name, str::number (defval)); + value = val.toInt(); +} + +void floatconfig::loadFromConfig (const QSettings* cfg) { + QVariant val = cfg->value (name, str::number (defval)); + value = val.toFloat(); +} + +void strconfig::loadFromConfig (const QSettings* cfg) { + QVariant val = cfg->value (name, defval); + value = val.toString(); +} + +void boolconfig::loadFromConfig (const QSettings* cfg) { + QVariant val = cfg->value (name, str::number (defval)); + value = val.toBool(); +} + +void keyseqconfig::loadFromConfig (const QSettings* cfg) { + QVariant val = cfg->value (name, defval.toString()); + value = keyseq (val.toString()); +} + +// ============================================================================= +// TODO: make virtual +str config::toString() const { + switch (getType()) { + case Type_int: + return fmt ("%1", static_cast (this)->value); + break; + + case Type_str: + return static_cast (this)->value; + break; + + case Type_float: + return fmt ("%1", static_cast (this)->value); + break; + + case Type_bool: + return (static_cast (this)->value) ? "true" : "false"; + break; + + case Type_keyseq: + return static_cast (this)->value.toString(); + break; + + default: + break; + } + + return ""; +} + +// ============================================================================= +// Save the configuration to disk +bool config::save() { + QSettings* settings = getSettingsObject(); + print ("Saving configuration to %1...\n", settings->fileName()); + + for (config* cfg : g_configPointers) { + if (!cfg) break; - case Type_bool: - valstring = (static_cast (cfg)->value) ? "true" : "false"; - break; - - case Type_keyseq: - valstring = static_cast (cfg)->value.toString(); - break; - - default: - break; - } - - // Write the entry now. - fprint (f, "%1=%2\n", cfg->name, valstring); + settings->setValue (cfg->name, cfg->toString()); } - f.close(); + settings->sync(); + settings->deleteLater(); return true; } @@ -196,21 +146,31 @@ } // ============================================================================= -str config::filepath() { - str path = fmt ("%1%2.cfg", dirpath(), str (APPNAME).toLower()); - return path; +str config::filepath (str file) { + return config::dirpath() + DIRSLASH + file; } // ============================================================================= str config::dirpath() { -#ifndef _WIN32 - return fmt ("%1" DIRSLASH ".%2" DIRSLASH, - QDir::homePath(), str (APPNAME).toLower()); -#else - return fmt ("%1" DIRSLASH APPNAME DIRSLASH, QDir::homePath()); -#endif // _WIN32 + QSettings* cfg = getSettingsObject(); + return dirname (cfg->fileName()); } +// ============================================================================= +str config::defaultString() const { + str defstring = m_defstring; + + // String types inevitably get extra quotes in their default string due to + // preprocessing stuff. We can only remove them now... + if (getType() == Type_str) { + defstring.remove (0, 1); + defstring.chop (1); + } + + return defstring; +} + +// ============================================================================= void addConfig (config* ptr) { if (g_cfgPointerCursor == 0) memset (g_configPointers, 0, sizeof g_configPointers);