1 /**
2 * @file configfile.c
3 * @brief handle configuration file
4 *
5 * Copyright (C) 2009 Gummi Developers
6 * All Rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following
15 * conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30 #include "configfile.h"
31
32 #include <glib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35
36 #include "constants.h"
37 #include "utils.h"
38
39
40 const gchar default_config[] =
41 "[General]\n"
42 "config_version = "C_PACKAGE_VERSION"\n"
43 "\n"
44 "[Interface]\n"
45 "mainwindow_x = 0\n"
46 "mainwindow_y = 0\n"
47 "mainwindow_w = 792\n"
48 "mainwindow_h = 558\n"
49 "mainwindow_max = false\n"
50 "toolbar = true\n"
51 "statusbar = true\n"
52 "snippets = true\n"
53 "[Editor]\n"
54 "font = Monospace 14\n"
55 "line_numbers = true\n"
56 "highlighting = true\n"
57 "textwrapping = true\n"
58 "wordwrapping = true\n"
59 "tabwidth = 4\n"
60 "spaces_instof_tabs = false\n"
61 "autoindentation = true\n"
62 "style_scheme = classic\n"
63 "spelling = false\n"
64 "spelling_lang = None\n"
65 "\n"
66 "[Preview]\n"
67 "zoom_mode = Fit Page Width\n"
68 "pagelayout = one_column\n"
69 "autosync = false\n"
70 "animated_scroll = always\n"
71 "cache_size = 150\n"
72 "\n"
73 "[File]\n"
74 "autosaving = false\n"
75 "autosave_timer = 10\n"
76 "autoexport = false\n"
77 "\n"
78 "[Compile]\n"
79 "typesetter = pdflatex\n"
80 "steps = texpdf\n"
81 "pause = false\n"
82 "scheme = on_idle\n"
83 "timer = 1\n"
84 "shellescape = true\n"
85 "synctex = false\n"
86 "\n"
87 "[Misc]\n"
88 "recent1 = __NULL__\n"
89 "recent2 = __NULL__\n"
90 "recent3 = __NULL__\n"
91 "recent4 = __NULL__\n"
92 "recent5 = __NULL__\n";
93
94 GKeyFile *key_file = NULL;
95 gchar *conf_filepath = 0;
96
97
config_init()98 void config_init () {
99 conf_filepath = g_build_filename (C_GUMMI_CONFDIR, "gummi.ini", NULL);
100
101 // create config & template dirs if not exists:
102 if (!g_file_test (C_GUMMI_TEMPLATEDIR, G_FILE_TEST_IS_DIR)) {
103 slog (L_WARNING, "Template directory does not exist, creating..\n");
104 g_mkdir_with_parents (C_GUMMI_TEMPLATEDIR, DIR_PERMS);
105 }
106
107 // load config file:
108 g_autoptr(GError) error = NULL;
109 key_file = g_key_file_new ();
110
111 if (!g_key_file_load_from_file (key_file, conf_filepath, G_KEY_FILE_NONE, &error)) {
112 if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
113 slog (L_WARNING, "Unable to load config, resetting defaults\n");
114 }
115 else {
116 slog (L_ERROR, "%s\n", error->message);
117 }
118 config_load_defaults (key_file);
119 }
120
121 // replace old welcome texts if still active:
122 gchar* text;
123 if (g_file_get_contents (C_WELCOMETEXT, &text, NULL, NULL)) {
124 guint hash = g_str_hash (text); // thank you mr daniel bernstein
125 if (hash == -676241409 || // 0.6.6
126 hash == 1654921927 || // 0.7.999
127 hash == 66148856) { // 0.8.0 dev
128 slog (L_WARNING, "Replacing unchanged welcome text with new default\n");
129 utils_copy_file (C_DEFAULTTEXT, C_WELCOMETEXT, NULL);
130 }
131 }
132 g_free (text);
133
134 slog (L_INFO, "Configuration file: %s\n", conf_filepath);
135 }
136
config_get_string(const gchar * group,const gchar * key)137 const gchar* config_get_string (const gchar* group, const gchar* key) {
138 g_autoptr(GError) error = NULL;
139 gchar* value;
140
141 value = g_key_file_get_string (key_file, group, key, &error);
142
143 if (error) {
144 return config_get_default_string (group, key);
145 }
146 return value;
147 }
148
config_get_boolean(const gchar * group,const gchar * key)149 const gboolean config_get_boolean (const gchar* group, const gchar* key) {
150 g_autoptr(GError) error = NULL;
151 gboolean value = FALSE;
152
153 value = g_key_file_get_boolean (key_file, group, key, &error);
154
155 if (error) {
156 return config_get_default_boolean (group, key);
157 }
158 return value;
159 }
160
config_get_integer(const gchar * group,const gchar * key)161 const gint config_get_integer (const gchar* group, const gchar* key) {
162 g_autoptr(GError) error = NULL;
163 gint value = FALSE;
164
165 value = g_key_file_get_integer (key_file, group, key, &error);
166
167 if (error) {
168 return config_get_default_integer (group, key);
169 }
170 return value;
171 }
172
config_get_default_string(const gchar * group,const gchar * key)173 const gchar* config_get_default_string (const gchar* group, const gchar* key) {
174 g_autoptr(GKeyFile) default_keys = g_key_file_new ();
175 gchar *default_value;
176
177 g_key_file_load_from_data (default_keys,
178 default_config,
179 strlen (default_config),
180 G_KEY_FILE_NONE, NULL);
181
182 slog (L_WARNING, "Config get default value for '%s.%s'\n", group, key);
183
184 default_value = g_key_file_get_string (default_keys, group, key, NULL);
185 config_set_string (group, key, default_value);
186
187 return default_value;
188 }
189
config_get_default_boolean(const gchar * group,const gchar * key)190 const gboolean config_get_default_boolean (const gchar* group, const gchar* key) {
191 g_autoptr(GKeyFile) default_keys = g_key_file_new ();
192 gboolean default_value;
193
194 g_key_file_load_from_data (default_keys,
195 default_config,
196 strlen (default_config),
197 G_KEY_FILE_NONE, NULL);
198
199 slog (L_WARNING, "Config get default value for '%s.%s'\n", group, key);
200
201 default_value = g_key_file_get_boolean (default_keys, group, key, NULL);
202 config_set_boolean (group, key, default_value);
203
204 return default_value;
205 }
206
config_get_default_integer(const gchar * group,const gchar * key)207 const gint config_get_default_integer (const gchar* group, const gchar* key) {
208 g_autoptr(GKeyFile) default_keys = g_key_file_new ();
209 gint default_value;
210
211 g_key_file_load_from_data (default_keys,
212 default_config,
213 strlen (default_config),
214 G_KEY_FILE_NONE, NULL);
215
216 slog (L_WARNING, "Config get default value for '%s.%s'\n", group, key);
217
218 default_value = g_key_file_get_integer (default_keys, group, key, NULL);
219 config_set_integer (group, key, default_value);
220
221 return default_value;
222 }
223
config_value_as_str_equals(const gchar * group,const gchar * key,gchar * input)224 gboolean config_value_as_str_equals (const gchar* group, const gchar* key, gchar* input) {
225 const gchar* value;
226
227 value = config_get_string (group, key);
228 if STR_EQU (value, input) {
229 return TRUE;
230 }
231 return FALSE;
232 }
233
config_set_string(const gchar * group,const gchar * key,gchar * value)234 void config_set_string (const gchar *group, const gchar *key, gchar* value) {
235 g_key_file_set_string (key_file, group, key, value);
236 }
237
config_set_boolean(const gchar * group,const gchar * key,gboolean value)238 void config_set_boolean (const gchar *group, const gchar *key, gboolean value) {
239 g_key_file_set_boolean (key_file, group, key, value);
240 }
241
config_set_integer(const gchar * group,const gchar * key,gint value)242 void config_set_integer (const gchar *group, const gchar *key, gint value) {
243 g_key_file_set_integer (key_file, group, key, value);
244 }
245
config_load_defaults()246 void config_load_defaults () {
247 g_autoptr(GError) error = NULL;
248
249 g_key_file_load_from_data (key_file, default_config, strlen(default_config),
250 G_KEY_FILE_NONE, &error);
251
252 if (error) {
253 slog (L_ERROR, "Error loading default config: %s\n", error->message);
254 }
255 config_save ();
256 }
257
config_save()258 void config_save () {
259 g_autoptr(GError) error = NULL;
260
261 if (!g_key_file_save_to_file (key_file, conf_filepath, &error)) {
262 if (error) {
263 slog (L_ERROR, "Error saving config: %s\n", error->message);
264 }
265 }
266 }
267