improve settings

This commit is contained in:
Vadim Lopatin 2015-02-16 10:27:25 +03:00
parent 06d1f31cd0
commit 9b3c2b3cfc
2 changed files with 164 additions and 4 deletions

View File

@ -32,6 +32,9 @@ import std.algorithm : equal;
import std.conv : to;
import std.utf : encode;
import std.math : pow;
import std.file;
import std.path;
import std.datetime : SysTime;
/// setting types - same as in std.json
enum SettingType {
@ -46,6 +49,89 @@ enum SettingType {
NULL
}
/// Settings object whith file information
class SettingsFile {
protected Setting _setting;
protected string _filename;
protected SysTime _lastModificationTime;
protected bool _loaded;
@property Setting setting() { return _setting; }
alias setting this;
/// create settings file object; if filename is provided, attempts to load settings from file
this(string filename = null) {
_setting = new Setting();
_filename = filename;
if (_filename) {
string dir = baseName(_filename);
if (load()) {
// loaded ok
} else {
}
}
}
@property bool loaded() {
return _loaded;
}
/// filename
@property string filename() { return _filename; }
/// filename
@property void filename(string fn) { _filename = fn; }
protected bool updateModificationTime() {
if (_filename is null)
return false;
try {
if (!_filename.exists || !_filename.isFile)
return false;
SysTime accTime;
getTimes(_filename, accTime, _lastModificationTime);
return true;
} catch (Exception e) {
return false;
}
}
/// load settings from file
bool load(string filename = null) {
if (filename !is null)
_filename = filename;
assert(_filename !is null);
if (updateModificationTime()) {
bool res = _setting.load(_filename);
if (res)
_loaded = true;
return res;
}
return false;
}
/// save settings to file
bool save(string filename = null, bool pretty = true) {
if (filename !is null)
_filename = filename;
assert(_filename);
string dir = baseName(_filename);
if (!dir.exists) {
try {
mkdirRecurse(dir);
} catch (Exception e) {
return false;
}
} else if (!dir.isDir) {
Log.d("", dir, " is file");
return false;
}
bool res = _setting.save(_filename, pretty);
res = updateModificationTime() || res;
return res;
}
}
/// setting object
final class Setting {
union Store {
@ -94,6 +180,7 @@ final class Setting {
_changed = changed;
}
/// array
private static struct SettingArray {
Setting[] list;
@ -216,7 +303,18 @@ final class Setting {
return v;
}
/// returns SettingType of setting
@property SettingType type() const { return _type; }
@property bool isString() { return _type == SettingType.STRING; }
@property bool isInteger() { return _type == SettingType.INTEGER; }
@property bool isUinteger() { return _type == SettingType.UINTEGER; }
@property bool isFloating() { return _type == SettingType.FLOAT; }
@property bool isObject() { return _type == SettingType.OBJECT; }
@property bool isArray() { return _type == SettingType.ARRAY; }
@property bool isBoolean() { return _type == SettingType.TRUE || _type == SettingType.FALSE; }
@property bool isNull() { return _type == SettingType.NULL; }
/// clear value and set new type
void clear(SettingType newType) {
if (newType != _type) {
@ -1289,9 +1387,15 @@ final class Setting {
}
}
void save(string filename, bool pretty = true) {
import std.file;
write(filename, toJSON(pretty));
/// save to file
bool save(string filename, bool pretty = true) {
try {
write(filename, toJSON(pretty));
return true;
} catch (Exception e) {
Log.e("exception while saving settings file: ", e);
return false;
}
}
private static struct JsonParser {
@ -1631,7 +1735,6 @@ final class Setting {
bool load(string filename) {
try {
import std.file;
string s = readText(filename);
parseJSON(s);
return true;

View File

@ -23,6 +23,9 @@ import dlangui.widgets.menu;
import dlangui.widgets.layouts;
import dlangui.widgets.statusline;
import dlangui.widgets.toolbars;
import dlangui.core.files;
import dlangui.core.settings;
import std.path;
/// to update status for background operation in AppFrame
class BackgroundOperationWatcher {
@ -76,6 +79,60 @@ class AppFrame : VerticalLayout, MenuItemClickHandler, MenuItemActionHandler {
protected BackgroundOperationWatcher _currentBackgroundOperation;
protected ulong _currentBackgroundOperationTimer;
protected string _appName = "dlangui";
/// override to return some identifier for app, e.g. to use as settings directory name
@property string appCodeName() {
return _appName;
}
/// override to return some identifier for app, e.g. to use as settings directory name
@property AppFrame appCodeName(string name) {
_appName = name;
return this;
}
protected string _settingsDir;
/// Application settings directory; by default, returns .appcodename directory in user's home directory (e.g. /home/user/.appcodename, C:\Users\User\AppData\Roaming\.appcodename); override to change it
@property string settingsDir() {
if (!_settingsDir)
_settingsDir = appDataPath("." ~ appCodeName);
return _settingsDir;
}
protected SettingsFile _shortcutSettings;
/// returns shortcuts settings object
@property SettingsFile shortcutSettings() {
if (!_shortcutSettings) {
_shortcutSettings = new SettingsFile(buildNormalizedPath(settingsDir, "shortcuts.json"));
}
return _shortcutSettings;
}
bool applyShortcutsSettings() {
if (shortcutSettings.loaded) {
foreach(key, value; _shortcutSettings.map) {
int actionId = actionNameToId(key);
if (actionId == 0) {
Log.e("applyShortcutsSettings: Unknown action name: ", key);
} else {
Accelerator[] accelerators;
if (value.isArray) {
for (int i = 0; i < value.length; i++) {
string v = value[i].str;
}
} else {
string v = value.str;
}
// TODO: parse accelerators
setActionAccelerators(actionId, accelerators);
}
}
return true;
}
return false;
}
/// timer handler
override bool onTimer(ulong timerId) {
if (timerId == _currentBackgroundOperationTimer) {