diff --git a/src/dlangui/core/settings.d b/src/dlangui/core/settings.d index c5c8b183..3bab9835 100644 --- a/src/dlangui/core/settings.d +++ b/src/dlangui/core/settings.d @@ -1,19 +1,32 @@ module dlangui.core.settings; import std.range; +import std.algorithm; +import std.conv; /// access to settings +/// keys may be either simple key identifier or path delimited by / (e.g. setting1/subsetting2/subsetting15) interface Settings { /// returns true if settings object has specified key bool hasKey(string key); /// returns reference to parent settings @property Settings parent(); /// get string by key, returns defValue if no such key - string getString(string key, string defValue); + string getString(string key, string defValue = null); /// set string for key, returns old value or null if not set string setString(string key, string value); + /// get bool by key, returns defValue if no such key + bool getBool(string key, bool defValue = false); + /// set bool for key, returns old value or null if not set + bool setBool(string key, bool value); + /// get bool by key, returns defValue if no such key + int getInt(string key, int defValue = 0); + /// set bool for key, returns old value or null if not set + int setInt(string key, int value); /// remove setting, returns true if removed, false if no such key bool remove(string key); + /// child subsettings access + Settings child(string key, bool createIfNotExist = false); } /// implementation of settings object @@ -47,9 +60,8 @@ class SettingsImpl : Settings { } return false; } - /// get string by key, returns defValue if no such key - override string getString(string key, string defValue) { + override string getString(string key, string defValue = null) { string part1, part2; if (splitKey(key, part1, part2)) { // path @@ -100,6 +112,35 @@ class SettingsImpl : Settings { return (key in _values) !is null; } } + + override Settings child(string key, bool createIfNotExist = false) { + string part1, part2; + if (splitKey(key, part1, part2)) { + auto p = (part1 in _children); + if (!p) { + if (!createIfNotExist) + return null; + SettingsImpl newItem = new SettingsImpl(this); + _children[part1] = newItem; + return newItem.child(part2, createIfNotExist); + } else { + return (*p).child(part2); + } + } else { + auto p = (key in _children); + if (!p) { + if (!createIfNotExist) + return null; + SettingsImpl newItem = new SettingsImpl(this); + _children[key] = newItem; + return newItem; + } else { + return (*p); + } + } + } + + /// remove setting, returns true if removed, false if no such key bool remove(string key) { string part1, part2; @@ -114,4 +155,64 @@ class SettingsImpl : Settings { return _values.remove(key); } } + + static bool parseBool(string v, bool defValue) { + int len = cast(int)v.length; + if (len == 0) + return defValue; + char ch = v[0]; + if (len == 1) { + if (ch == '1' || ch == 'y' || ch == 't') + return true; + if (ch == '1' || ch == 'y' || ch == 't') + return false; + return defValue; + } + if (v.equal("yes") || v.equal("true")) + return true; + if (v.equal("no") || v.equal("false")) + return false; + return defValue; + } + + static int parseInt(string v, int defValue) { + int len = cast(int)v.length; + if (len == 0) + return defValue; + int sign = 1; + int value = 0; + int digits = 0; + for (int i = 0; i < len; i++) { + char ch = v[i]; + if (ch == '-') { + if (i != 0) + return defValue; + sign = -1; + } else if (ch >= '0' && ch <= '9') { + digits++; + value = value * 10 + (ch - '0'); + } else { + return defValue; + } + } + return digits > 0 ? (sign > 0 ? value : -value) : defValue; + } + + /// get bool by key, returns defValue if no such key + bool getBool(string key, bool defValue = false) { + return parseBool(getString(key, ""), defValue); + } + /// set bool for key, returns old value or null if not set + bool setBool(string key, bool value) { + return parseBool(setString(key, value ? "1" : "0"), false); + } + + /// get bool by key, returns defValue if no such key + int getInt(string key, int defValue = 0) { + return parseInt(getString(key, ""), defValue); + } + /// set bool for key, returns old value or null if not set + int setInt(string key, int value) { + return parseInt(setString(key, to!string(value)), false); + } }