1 #include <calf/gui_config.h>
2 #include <assert.h>
3 #include <stdio.h>
4 
5 using namespace std;
6 using namespace calf_utils;
7 
gui_config()8 gui_config::gui_config()
9 {
10     rack_float       = 0;
11     float_size       = 1;
12     rack_ears        = true;
13     vu_meters        = true;
14     win_to_tray      = false;
15     win_start_hidden = false;
16     style       = "Calf_Default";
17 }
18 
~gui_config()19 gui_config::~gui_config()
20 {
21 }
22 
load(config_db_iface * db)23 void gui_config::load(config_db_iface *db)
24 {
25     rack_float       = db->get_int("rack-float", gui_config().rack_float);
26     float_size       = db->get_int("float-size", gui_config().float_size);
27     rack_ears        = db->get_bool("show-rack-ears", gui_config().rack_ears);
28     vu_meters        = db->get_bool("show-vu-meters", gui_config().vu_meters);
29     style            = db->get_string("style", gui_config().style);
30     win_to_tray      = db->get_bool("win-to-tray", gui_config().win_to_tray);
31     win_start_hidden = db->get_bool("win-start-hidden", gui_config().win_start_hidden);
32 }
33 
save(config_db_iface * db)34 void gui_config::save(config_db_iface *db)
35 {
36     db->set_int("rack-float", rack_float);
37     db->set_int("float-size", float_size);
38     db->set_bool("show-rack-ears", rack_ears);
39     db->set_bool("show-vu-meters", vu_meters);
40     db->set_string("style", style);
41     db->set_bool("win-to-tray", win_to_tray);
42     db->set_bool("win-start-hidden", win_start_hidden);
43     db->save();
44 }
45 
46 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 
notifier(gkeyfile_config_db * _parent,config_listener_iface * _listener)48 gkeyfile_config_db::notifier::notifier(gkeyfile_config_db *_parent, config_listener_iface *_listener)
49 {
50     parent = _parent;
51     listener = _listener;
52 }
53 
~notifier()54 gkeyfile_config_db::notifier::~notifier()
55 {
56     parent->remove_notifier(this);
57  }
58 
59 
60 ////////////////////////////////////////////////////////////////////////////////////////////////////
61 
gkeyfile_config_db(GKeyFile * kf,const char * _filename,const char * _section)62 gkeyfile_config_db::gkeyfile_config_db(GKeyFile *kf, const char *_filename, const char *_section)
63 {
64     keyfile = kf;
65     filename = _filename;
66     section = _section;
67 }
68 
handle_error(GError * error)69 void gkeyfile_config_db::handle_error(GError *error)
70 {
71     if (error)
72     {
73         string msg = error->message;
74         g_error_free(error);
75         throw config_exception(msg.c_str());
76     }
77 }
78 
remove_notifier(notifier * n)79 void gkeyfile_config_db::remove_notifier(notifier *n)
80 {
81     for (size_t i = 0; i < notifiers.size(); i++)
82     {
83         if (notifiers[i] == n)
84         {
85             notifiers.erase(notifiers.begin() + i);
86             return;
87         }
88     }
89     assert(0);
90 }
91 
has_dir(const char * key)92 bool gkeyfile_config_db::has_dir(const char *key)
93 {
94     return g_key_file_has_group(keyfile, key);
95 }
96 
check_not_found_and_delete(GError * error)97 static bool check_not_found_and_delete(GError *error)
98 {
99     if (error && error->domain == G_KEY_FILE_ERROR)
100     {
101         switch(error->code)
102         {
103             case G_KEY_FILE_ERROR_KEY_NOT_FOUND:
104             case G_KEY_FILE_ERROR_GROUP_NOT_FOUND:
105                 g_error_free(error);
106                 return true;
107             default:
108                 return false;
109         }
110     }
111     return false;
112 }
113 
get_bool(const char * key,bool def_value)114 bool gkeyfile_config_db::get_bool(const char *key, bool def_value)
115 {
116     GError *err = NULL;
117     bool value = (bool)g_key_file_get_boolean(keyfile, section.c_str(), key, &err);
118     if (err)
119     {
120         if (check_not_found_and_delete(err))
121             return def_value;
122         handle_error(err);
123     }
124     return value;
125 }
126 
get_int(const char * key,int def_value)127 int gkeyfile_config_db::get_int(const char *key, int def_value)
128 {
129     GError *err = NULL;
130     int value = g_key_file_get_integer(keyfile, section.c_str(), key, &err);
131     if (err)
132     {
133         if (check_not_found_and_delete(err))
134             return def_value;
135         handle_error(err);
136     }
137     return value;
138 }
139 
get_string(const char * key,const std::string & def_value)140 std::string gkeyfile_config_db::get_string(const char *key, const std::string &def_value)
141 {
142     GError *err = NULL;
143     gchar *value = g_key_file_get_string(keyfile, section.c_str(), key, &err);
144     if (err)
145     {
146         if (check_not_found_and_delete(err))
147             return def_value;
148         handle_error(err);
149     }
150     return value;
151 }
152 
set_bool(const char * key,bool value)153 void gkeyfile_config_db::set_bool(const char *key, bool value)
154 {
155     g_key_file_set_boolean(keyfile, section.c_str(), key, (gboolean)value);
156 }
157 
set_int(const char * key,int value)158 void gkeyfile_config_db::set_int(const char *key, int value)
159 {
160     g_key_file_set_integer(keyfile, section.c_str(), key, value);
161 }
162 
set_string(const char * key,const std::string & value)163 void gkeyfile_config_db::set_string(const char *key, const std::string &value)
164 {
165     g_key_file_set_string(keyfile, section.c_str(), key, value.c_str());
166 }
167 
save()168 void gkeyfile_config_db::save()
169 {
170     GError *err = NULL;
171     gsize length = 0;
172     gchar *data = g_key_file_to_data(keyfile, &length, &err);
173     if (err)
174         handle_error(err);
175 
176     if (!g_file_set_contents(filename.c_str(), data, length, &err))
177     {
178         g_free(data);
179         handle_error(err);
180     }
181     g_free(data);
182 
183     for (size_t i = 0; i < notifiers.size(); i++)
184         notifiers[i]->listener->on_config_change();
185 }
186 
add_listener(config_listener_iface * listener)187 config_notifier_iface *gkeyfile_config_db::add_listener(config_listener_iface *listener)
188 {
189     notifier *n = new notifier(this, listener);
190     notifiers.push_back(n);
191     return n;
192 }
193 
~gkeyfile_config_db()194 gkeyfile_config_db::~gkeyfile_config_db()
195 {
196 }
197