Tue, 27 May 2003 03:38:52 +0000
[gaim-migrate @ 5937]
This is:
-AIM over OSCAR use Christian's new, kick ass
gaim_notify_email stuff for new mail notification. This
should be good, but it's kind of a pain to test. Let me
know if you have any problems
-Minor fix to the translation README
-2 minor changes to the doxygen of 2 major header files
(this means you'll have to recompile a lot of files :-) )
-If your global proxy setting is "No Proxy" and your global
proxy host is empty, but $http_proxy is set to something,
gaim used to switch your global proxy setting to "HTTP." It
no longer does this. This makes more sense to me. If you
disagree, please let me know--this is open to debate, and
what not. Also, the use of environmental proxy settings
will be changed a bit in the next day or two
| 1 | 1 | /* |
| 2 | * gaim | |
| 3 | * | |
| 5440 | 4 | * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> |
| 1 | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | |
| 7 | * it under the terms of the GNU General Public License as published by | |
| 8 | * the Free Software Foundation; either version 2 of the License, or | |
| 9 | * (at your option) any later version. | |
| 10 | * | |
| 11 | * This program is distributed in the hope that it will be useful, | |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | * GNU General Public License for more details. | |
| 15 | * | |
| 16 | * You should have received a copy of the GNU General Public License | |
| 17 | * along with this program; if not, write to the Free Software | |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 | * | |
| 20 | */ | |
| 21 | ||
|
349
6f7d28b0f98d
[gaim-migrate @ 359]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
340
diff
changeset
|
22 | #ifdef HAVE_CONFIG_H |
|
2090
bab8b7e309db
[gaim-migrate @ 2100]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2074
diff
changeset
|
23 | #include <config.h> |
|
349
6f7d28b0f98d
[gaim-migrate @ 359]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
340
diff
changeset
|
24 | #endif |
| 5440 | 25 | |
| 1 | 26 | #include <string.h> |
| 27 | #include <stdio.h> | |
| 28 | #include <stdlib.h> | |
| 5440 | 29 | #include <sys/stat.h> |
| 30 | #include <sys/types.h> | |
| 31 | #include <glib.h> | |
| 32 | #include "prefs.h" | |
| 33 | #include "debug.h" | |
| 34 | #include "util.h" | |
| 3366 | 35 | |
|
4026
4ec5559caae9
[gaim-migrate @ 4230]
Herman Bloggs <herman@bluedigits.com>
parents:
4010
diff
changeset
|
36 | #ifdef _WIN32 |
|
4ec5559caae9
[gaim-migrate @ 4230]
Herman Bloggs <herman@bluedigits.com>
parents:
4010
diff
changeset
|
37 | #include "win32dep.h" |
|
4ec5559caae9
[gaim-migrate @ 4230]
Herman Bloggs <herman@bluedigits.com>
parents:
4010
diff
changeset
|
38 | #endif |
|
4ec5559caae9
[gaim-migrate @ 4230]
Herman Bloggs <herman@bluedigits.com>
parents:
4010
diff
changeset
|
39 | |
| 5440 | 40 | struct pref_cb { |
| 41 | GaimPrefCallback func; | |
| 42 | gpointer data; | |
| 43 | guint id; | |
| 44 | }; | |
| 45 | ||
| 46 | struct gaim_pref { | |
| 47 | GaimPrefType type; | |
| 48 | char *name; | |
| 49 | union { | |
| 50 | gpointer generic; | |
| 51 | gboolean boolean; | |
| 52 | int integer; | |
| 53 | char *string; | |
| 54 | } value; | |
| 55 | GSList *callbacks; | |
| 56 | struct gaim_pref *parent; | |
| 57 | struct gaim_pref *sibling; | |
| 58 | struct gaim_pref *first_child; | |
| 59 | }; | |
| 3366 | 60 | |
| 5440 | 61 | static GHashTable *prefs_hash = NULL; |
| 62 | ||
| 63 | static struct gaim_pref prefs = { GAIM_PREF_NONE, NULL, {NULL}, NULL, | |
| 64 | NULL, NULL, NULL }; | |
| 65 | ||
| 5534 | 66 | static guint prefs_save_timer = 0; |
| 67 | static gboolean prefs_is_loaded = FALSE; | |
| 68 | ||
| 69 | ||
| 70 | static gboolean prefs_save_callback(gpointer who_cares) { | |
| 71 | gaim_prefs_sync(); | |
| 72 | prefs_save_timer = 0; | |
| 73 | return FALSE; | |
| 74 | } | |
| 75 | ||
| 76 | static void schedule_prefs_save() { | |
| 77 | if(!prefs_save_timer) | |
| 78 | prefs_save_timer = g_timeout_add(5000, prefs_save_callback, NULL); | |
| 79 | } | |
| 80 | ||
| 81 | static void prefs_save_cb(const char *name, GaimPrefType type, gpointer val, | |
| 82 | gpointer user_data) { | |
| 83 | ||
| 84 | if(!prefs_is_loaded) | |
| 85 | return; | |
| 86 | ||
| 87 | gaim_debug(GAIM_DEBUG_MISC, "prefs", "%s changed, scheduling save.\n", name); | |
| 88 | ||
| 89 | schedule_prefs_save(); | |
| 90 | } | |
| 91 | ||
| 5440 | 92 | void gaim_prefs_init() { |
| 93 | prefs_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | |
| 94 | ||
| 5534 | 95 | gaim_prefs_connect_callback("/", prefs_save_cb, NULL); |
| 96 | ||
|
5529
4a9fd5f1a400
[gaim-migrate @ 5929]
Christian Hammond <chipx86@chipx86.com>
parents:
5458
diff
changeset
|
97 | gaim_prefs_add_none("/core"); |
|
4a9fd5f1a400
[gaim-migrate @ 5929]
Christian Hammond <chipx86@chipx86.com>
parents:
5458
diff
changeset
|
98 | |
| 5440 | 99 | /* XXX: this is where you would want to put prefs declarations */ |
| 100 | } | |
| 3366 | 101 | |
| 5440 | 102 | static char *pref_full_name(struct gaim_pref *pref) { |
| 103 | GString *name; | |
| 104 | struct gaim_pref *parent; | |
| 105 | if(!pref) | |
| 106 | return NULL; | |
| 107 | ||
| 108 | if(pref == &prefs) | |
| 109 | return g_strdup("/"); | |
| 110 | ||
| 111 | name = g_string_new(pref->name); | |
| 112 | parent = pref->parent; | |
| 3366 | 113 | |
| 5440 | 114 | for(parent = pref->parent; parent && parent->name; parent = parent->parent) { |
| 115 | name = g_string_prepend_c(name, '/'); | |
| 116 | name = g_string_prepend(name, parent->name); | |
| 117 | } | |
| 118 | g_string_free(name, FALSE); | |
| 119 | return name->str; | |
| 120 | } | |
| 121 | ||
| 122 | static struct gaim_pref *find_pref(const char *name) | |
| 123 | { | |
| 124 | if(!name || name[0] != '/') { | |
| 125 | return NULL; | |
| 126 | } else if(name[1] == '\0') { | |
| 127 | return &prefs; | |
| 128 | } else { | |
| 129 | return g_hash_table_lookup(prefs_hash, name); | |
| 130 | } | |
| 131 | } | |
| 132 | ||
| 133 | static struct gaim_pref *find_pref_parent(const char *name) | |
| 134 | { | |
| 135 | char *parent_name = g_path_get_dirname(name); | |
| 136 | struct gaim_pref *ret = &prefs; | |
| 137 | ||
| 138 | if(strcmp(parent_name, "/")) { | |
| 139 | ret = find_pref(parent_name); | |
| 140 | } | |
| 1026 | 141 | |
| 5440 | 142 | g_free(parent_name); |
| 143 | return ret; | |
| 144 | } | |
| 145 | ||
| 146 | static void free_pref_value(struct gaim_pref *pref) { | |
| 147 | switch(pref->type) { | |
| 148 | case GAIM_PREF_BOOLEAN: | |
| 149 | pref->value.boolean = FALSE; | |
| 150 | case GAIM_PREF_INT: | |
| 151 | pref->value.integer = 0; | |
| 152 | break; | |
| 153 | case GAIM_PREF_STRING: | |
| 154 | g_free(pref->value.string); | |
| 155 | pref->value.string = NULL; | |
| 156 | break; | |
| 157 | case GAIM_PREF_NONE: | |
| 158 | break; | |
| 159 | } | |
| 160 | } | |
| 161 | ||
| 162 | static struct gaim_pref *add_pref(GaimPrefType type, const char *name) { | |
| 163 | struct gaim_pref *parent; | |
| 164 | struct gaim_pref *me; | |
| 165 | struct gaim_pref *sibling; | |
|
5458
b360ef43126d
[gaim-migrate @ 5846]
Christian Hammond <chipx86@chipx86.com>
parents:
5451
diff
changeset
|
166 | char *my_name; |
| 5440 | 167 | |
| 168 | parent = find_pref_parent(name); | |
| 169 | ||
| 170 | if(!parent) | |
| 171 | return NULL; | |
|
1525
b4ece1a718cd
[gaim-migrate @ 1535]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1455
diff
changeset
|
172 | |
|
5458
b360ef43126d
[gaim-migrate @ 5846]
Christian Hammond <chipx86@chipx86.com>
parents:
5451
diff
changeset
|
173 | my_name = g_path_get_basename(name); |
|
b360ef43126d
[gaim-migrate @ 5846]
Christian Hammond <chipx86@chipx86.com>
parents:
5451
diff
changeset
|
174 | |
| 5440 | 175 | for(sibling = parent->first_child; sibling; sibling = sibling->sibling) { |
| 176 | if(!strcmp(sibling->name, my_name)) { | |
| 177 | g_free(my_name); | |
| 178 | return NULL; | |
| 179 | } | |
| 180 | } | |
| 181 | ||
| 182 | me = g_new0(struct gaim_pref, 1); | |
| 183 | me->type = type; | |
| 184 | me->name = my_name; | |
| 185 | ||
| 186 | me->parent = parent; | |
| 187 | if(parent->first_child) { | |
| 188 | /* blatant abuse of a for loop */ | |
| 189 | for(sibling = parent->first_child; sibling->sibling; | |
| 190 | sibling = sibling->sibling); | |
| 191 | sibling->sibling = me; | |
| 192 | } else { | |
| 193 | parent->first_child = me; | |
| 194 | } | |
| 195 | ||
| 196 | g_hash_table_insert(prefs_hash, g_strdup(name), (gpointer)me); | |
| 197 | ||
| 198 | return me; | |
| 199 | } | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
200 | |
| 5440 | 201 | void gaim_prefs_add_none(const char *name) { |
| 202 | add_pref(GAIM_PREF_NONE, name); | |
| 203 | } | |
| 204 | ||
| 205 | void gaim_prefs_add_bool(const char *name, gboolean value) { | |
| 206 | struct gaim_pref *pref = add_pref(GAIM_PREF_BOOLEAN, name); | |
| 207 | ||
| 208 | if(!pref) | |
| 209 | return; | |
| 210 | ||
| 211 | pref->value.boolean = value; | |
| 212 | } | |
| 3630 | 213 | |
| 5440 | 214 | void gaim_prefs_add_int(const char *name, int value) { |
| 215 | struct gaim_pref *pref = add_pref(GAIM_PREF_INT, name); | |
| 216 | ||
| 217 | if(!pref) | |
| 218 | return; | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
219 | |
| 5440 | 220 | pref->value.integer = value; |
| 221 | } | |
| 222 | ||
| 223 | void gaim_prefs_add_string(const char *name, const char *value) { | |
| 224 | struct gaim_pref *pref = add_pref(GAIM_PREF_STRING, name); | |
| 225 | ||
| 226 | if(!pref) | |
| 227 | return; | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
228 | |
| 5440 | 229 | pref->value.string = g_strdup(value); |
| 230 | } | |
| 231 | ||
| 232 | void remove_pref(struct gaim_pref *pref) { | |
| 233 | char *name; | |
| 234 | ||
| 235 | if(!pref || pref == &prefs) | |
| 236 | return; | |
| 237 | ||
| 238 | if(pref->parent->first_child == pref) { | |
| 239 | pref->parent->first_child = pref->sibling; | |
| 240 | } else { | |
| 241 | struct gaim_pref *sib = pref->parent->first_child; | |
| 242 | while(sib->sibling != pref) | |
| 243 | sib = sib->sibling; | |
| 244 | sib->sibling = pref->sibling; | |
| 245 | } | |
| 246 | ||
| 247 | name = pref_full_name(pref); | |
| 248 | ||
| 249 | g_hash_table_remove(prefs_hash, name); | |
| 250 | g_free(name); | |
| 251 | ||
| 252 | free_pref_value(pref); | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
253 | |
| 5440 | 254 | g_slist_free(pref->callbacks); |
| 255 | g_free(pref->name); | |
| 256 | g_free(pref); | |
| 257 | } | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
258 | |
| 5440 | 259 | void gaim_prefs_remove(const char *name) { |
| 260 | struct gaim_pref *pref = find_pref(name); | |
| 261 | struct gaim_pref *child, *child2; | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
262 | |
| 5440 | 263 | if(!pref) |
| 264 | return; | |
| 265 | child = pref->first_child; | |
| 266 | while(child) { | |
| 267 | child2 = child; | |
| 268 | child = child->sibling; | |
| 269 | remove_pref(child2); | |
| 270 | } | |
| 271 | ||
| 272 | remove_pref(pref); | |
| 273 | } | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
274 | |
| 5440 | 275 | void gaim_prefs_destroy() { |
| 276 | gaim_prefs_remove("/"); | |
| 277 | } | |
| 278 | ||
| 279 | static void do_callbacks(const char* name, struct gaim_pref *pref) { | |
| 280 | GSList *cbs; | |
| 281 | struct gaim_pref *cb_pref; | |
| 282 | for(cb_pref = pref; cb_pref; cb_pref = cb_pref->parent) { | |
| 283 | for(cbs = cb_pref->callbacks; cbs; cbs = cbs->next) { | |
| 284 | struct pref_cb *cb = cbs->data; | |
| 285 | cb->func(name, pref->type, pref->value.generic, cb->data); | |
| 4215 | 286 | } |
| 287 | } | |
|
1525
b4ece1a718cd
[gaim-migrate @ 1535]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1455
diff
changeset
|
288 | } |
|
b4ece1a718cd
[gaim-migrate @ 1535]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1455
diff
changeset
|
289 | |
| 5440 | 290 | void gaim_prefs_set_generic(const char *name, gpointer value) { |
| 291 | struct gaim_pref *pref = find_pref(name); | |
| 3366 | 292 | |
| 5440 | 293 | g_return_if_fail(pref != NULL); |
| 3500 | 294 | |
| 5440 | 295 | pref->value.generic = value; |
| 296 | do_callbacks(name, pref); | |
| 3366 | 297 | } |
| 298 | ||
| 5440 | 299 | void gaim_prefs_set_bool(const char *name, gboolean value) { |
| 300 | struct gaim_pref *pref = find_pref(name); | |
| 4288 | 301 | |
| 5533 | 302 | if(pref) { |
| 303 | g_return_if_fail(pref->type == GAIM_PREF_BOOLEAN); | |
| 4325 | 304 | |
| 5533 | 305 | if(pref->value.boolean != value) { |
| 306 | pref->value.boolean = value; | |
| 307 | do_callbacks(name, pref); | |
| 308 | } | |
| 309 | } else { | |
| 310 | gaim_prefs_add_bool(name, value); | |
| 4288 | 311 | } |
| 4324 | 312 | } |
| 4325 | 313 | |
| 5440 | 314 | void gaim_prefs_set_int(const char *name, int value) { |
| 315 | struct gaim_pref *pref = find_pref(name); | |
| 4325 | 316 | |
| 5533 | 317 | if(pref) { |
| 318 | g_return_if_fail(pref->type == GAIM_PREF_INT); | |
| 4325 | 319 | |
| 5533 | 320 | if(pref->value.integer != value) { |
| 321 | pref->value.integer = value; | |
| 322 | do_callbacks(name, pref); | |
| 323 | } | |
| 324 | } else { | |
| 325 | gaim_prefs_add_int(name, value); | |
| 5440 | 326 | } |
| 4326 | 327 | } |
| 328 | ||
| 5451 | 329 | void gaim_prefs_set_string(const char *name, const char *value) { |
| 5440 | 330 | struct gaim_pref *pref = find_pref(name); |
| 4325 | 331 | |
| 5533 | 332 | if(pref) { |
| 333 | g_return_if_fail(pref->type == GAIM_PREF_STRING); | |
| 4325 | 334 | |
| 5533 | 335 | if(strcmp(pref->value.string, value)) { |
| 336 | g_free(pref->value.string); | |
| 337 | pref->value.string = g_strdup(value); | |
| 338 | do_callbacks(name, pref); | |
| 339 | } | |
| 340 | } else { | |
| 341 | gaim_prefs_add_string(name, value); | |
| 4325 | 342 | } |
| 343 | } | |
| 344 | ||
| 5440 | 345 | gpointer gaim_prefs_get_generic(const char *name) { |
| 346 | struct gaim_pref *pref = find_pref(name); | |
| 4325 | 347 | |
| 5440 | 348 | g_return_val_if_fail(pref != NULL, NULL); |
| 4288 | 349 | |
| 5440 | 350 | return pref->value.generic; |
| 4288 | 351 | } |
| 352 | ||
| 5440 | 353 | gboolean gaim_prefs_get_bool(const char *name) { |
| 354 | struct gaim_pref *pref = find_pref(name); | |
| 3427 | 355 | |
| 5440 | 356 | g_return_val_if_fail(pref != NULL, FALSE); |
| 357 | g_return_val_if_fail(pref->type == GAIM_PREF_BOOLEAN, FALSE); | |
|
3472
3939deb42c1e
[gaim-migrate @ 3523]
Robert McQueen <robot101@debian.org>
parents:
3466
diff
changeset
|
358 | |
| 5440 | 359 | return pref->value.boolean; |
| 3366 | 360 | } |
| 361 | ||
| 5440 | 362 | int gaim_prefs_get_int(const char *name) { |
| 363 | struct gaim_pref *pref = find_pref(name); | |
| 3500 | 364 | |
| 5440 | 365 | g_return_val_if_fail(pref != NULL, 0); |
| 366 | g_return_val_if_fail(pref->type == GAIM_PREF_INT, 0); | |
| 3366 | 367 | |
| 5440 | 368 | return pref->value.integer; |
| 3366 | 369 | } |
| 370 | ||
| 5440 | 371 | char *gaim_prefs_get_string(const char *name) { |
| 372 | struct gaim_pref *pref = find_pref(name); | |
| 3366 | 373 | |
| 5440 | 374 | g_return_val_if_fail(pref != NULL, NULL); |
| 375 | g_return_val_if_fail(pref->type == GAIM_PREF_STRING, NULL); | |
|
4469
ef60c820b884
[gaim-migrate @ 4744]
Christian Hammond <chipx86@chipx86.com>
parents:
4461
diff
changeset
|
376 | |
| 5440 | 377 | return pref->value.string; |
|
4469
ef60c820b884
[gaim-migrate @ 4744]
Christian Hammond <chipx86@chipx86.com>
parents:
4461
diff
changeset
|
378 | } |
|
ef60c820b884
[gaim-migrate @ 4744]
Christian Hammond <chipx86@chipx86.com>
parents:
4461
diff
changeset
|
379 | |
| 5440 | 380 | guint gaim_prefs_connect_callback(const char *name, GaimPrefCallback func, gpointer data) |
| 381 | { | |
| 382 | struct gaim_pref *pref = find_pref(name); | |
| 383 | struct pref_cb *cb; | |
| 384 | static guint cb_id = 0; | |
| 3366 | 385 | |
| 5440 | 386 | if(!pref) |
| 387 | return 0; | |
| 3366 | 388 | |
| 5440 | 389 | cb = g_new0(struct pref_cb, 1); |
|
1881
bcd5d457cdbb
[gaim-migrate @ 1891]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1840
diff
changeset
|
390 | |
| 5440 | 391 | cb->func = func; |
| 392 | cb->data = data; | |
| 393 | cb->id = ++cb_id; | |
| 4991 | 394 | |
| 5440 | 395 | pref->callbacks = g_slist_append(pref->callbacks, cb); |
| 3366 | 396 | |
| 5440 | 397 | return cb->id; |
| 3366 | 398 | } |
| 399 | ||
| 5440 | 400 | gboolean disco_callback_helper(struct gaim_pref *pref, guint callback_id) { |
| 401 | GSList *cbs; | |
| 402 | struct gaim_pref *child; | |
| 2254 | 403 | |
| 5440 | 404 | if(!pref) |
| 405 | return FALSE; | |
|
1881
bcd5d457cdbb
[gaim-migrate @ 1891]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1840
diff
changeset
|
406 | |
| 5440 | 407 | for(cbs = pref->callbacks; cbs; cbs = cbs->next) { |
| 408 | struct pref_cb *cb = cbs->data; | |
| 409 | if(cb->id == callback_id) { | |
| 410 | pref->callbacks = g_slist_remove(pref->callbacks, cb); | |
| 411 | g_free(cb); | |
| 412 | return TRUE; | |
| 4428 | 413 | } |
| 414 | } | |
| 415 | ||
| 5440 | 416 | for(child = pref->first_child; child; child = child->sibling) { |
| 417 | if(disco_callback_helper(child, callback_id)) | |
| 418 | return TRUE; | |
| 4428 | 419 | } |
|
4451
5a484f11e395
[gaim-migrate @ 4726]
Herman Bloggs <herman@bluedigits.com>
parents:
4449
diff
changeset
|
420 | |
| 5440 | 421 | return FALSE; |
|
1757
8c57846a4691
[gaim-migrate @ 1767]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1755
diff
changeset
|
422 | } |
|
8c57846a4691
[gaim-migrate @ 1767]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1755
diff
changeset
|
423 | |
| 5440 | 424 | void gaim_prefs_disconnect_callback(guint callback_id) { |
| 425 | disco_callback_helper(&prefs, callback_id); | |
| 2262 | 426 | } |
| 427 | ||
| 5440 | 428 | static void gaim_prefs_write(FILE *f, struct gaim_pref *pref, int depth) { |
| 429 | struct gaim_pref *tmp; | |
| 430 | char *esc; | |
| 431 | int i; | |
| 3500 | 432 | |
| 5440 | 433 | if(!pref) { |
| 434 | pref = &prefs; | |
| 3551 | 435 | |
| 5440 | 436 | fprintf(f, "<?xml version='1.0' encoding='UTF-8' ?>\n"); |
| 437 | fprintf(f, "<pref name='/'"); | |
| 438 | } else { | |
| 439 | for(i=0; i<depth; i++) | |
| 440 | fprintf(f, "\t"); | |
| 441 | esc = g_markup_escape_text(pref->name, -1); | |
| 442 | fprintf(f, "<pref name='%s'", esc); | |
| 443 | g_free(esc); | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
444 | } |
|
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
445 | |
| 5440 | 446 | switch(pref->type) { |
| 447 | case GAIM_PREF_NONE: | |
| 448 | break; | |
| 449 | case GAIM_PREF_BOOLEAN: | |
| 450 | fprintf(f, " type='bool' value='%d'", pref->value.boolean); | |
| 451 | break; | |
| 452 | case GAIM_PREF_INT: | |
| 453 | fprintf(f, " type='int' value='%d'", pref->value.integer); | |
| 454 | break; | |
| 455 | case GAIM_PREF_STRING: | |
| 456 | esc = g_markup_escape_text(pref->value.string, -1); | |
| 457 | fprintf(f, " type='string' value='%s'", esc); | |
| 458 | g_free(esc); | |
| 459 | break; | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
460 | } |
|
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
461 | |
| 5440 | 462 | if(pref->first_child) { |
| 463 | fprintf(f, ">\n"); | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
464 | |
| 5440 | 465 | for(tmp = pref->first_child; tmp; tmp = tmp->sibling) |
| 466 | gaim_prefs_write(f, tmp, depth+1); | |
| 467 | for(i=0; i<depth; i++) | |
| 468 | fprintf(f, "\t"); | |
| 469 | fprintf(f, "</pref>\n"); | |
| 470 | } else { | |
| 471 | fprintf(f, " />\n"); | |
|
5205
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
472 | } |
|
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
473 | } |
|
242b8aa81328
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5105
diff
changeset
|
474 | |
| 5440 | 475 | void gaim_prefs_sync() { |
| 476 | FILE *file; | |
| 477 | const char *user_dir = gaim_user_dir(); | |
| 478 | char *filename; | |
| 479 | char *filename_real; | |
| 3551 | 480 | |
| 5534 | 481 | if(!prefs_is_loaded) { |
| 482 | gaim_debug(GAIM_DEBUG_WARNING, "prefs", "prefs saved before loading! scheduling save.\n"); | |
| 483 | schedule_prefs_save(); /* schedule a save for after we read in */ | |
| 484 | return; | |
| 485 | } | |
| 486 | ||
| 5440 | 487 | if(!user_dir) |
| 488 | return; | |
| 3551 | 489 | |
| 5534 | 490 | gaim_debug(GAIM_DEBUG_INFO, "prefs", "writing prefs out to disk.\n"); |
| 491 | ||
| 5440 | 492 | file = fopen(user_dir, "r"); |
| 493 | if(!file) | |
| 494 | mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
| 495 | else | |
| 496 | fclose(file); | |
| 3551 | 497 | |
| 5440 | 498 | filename = g_build_filename(user_dir, "prefs.xml.save", NULL); |
| 3551 | 499 | |
| 5440 | 500 | if((file = fopen(filename, "w"))) { |
| 501 | gaim_prefs_write(file, NULL, 0); | |
| 502 | fclose(file); | |
| 503 | chmod(filename, S_IRUSR | S_IWUSR); | |
| 504 | } else { | |
| 505 | gaim_debug(GAIM_DEBUG_ERROR, "prefs", "Unable to write %s\n", | |
| 506 | filename); | |
| 507 | } | |
| 3551 | 508 | |
| 5440 | 509 | filename_real = g_build_filename(user_dir, "prefs.xml", NULL); |
| 510 | if(rename(filename, filename_real) < 0) | |
| 511 | gaim_debug(GAIM_DEBUG_ERROR, "prefs", "Error renaming %s to %s\n", | |
| 512 | filename, filename_real); | |
| 3551 | 513 | |
| 5440 | 514 | g_free(filename); |
| 515 | g_free(filename_real); | |
| 3551 | 516 | } |
| 517 | ||
| 5440 | 518 | static GList *prefs_stack = NULL; |
|
873
d40eff5fc359
[gaim-migrate @ 883]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
864
diff
changeset
|
519 | |
| 5440 | 520 | static void prefs_start_element_handler (GMarkupParseContext *context, |
| 521 | const gchar *element_name, | |
| 522 | const gchar **attribute_names, | |
| 523 | const gchar **attribute_values, | |
| 524 | gpointer user_data, | |
| 525 | GError **error) { | |
| 526 | GaimPrefType pref_type = GAIM_PREF_NONE; | |
| 527 | int i; | |
| 528 | const char *pref_name = NULL, *pref_value = NULL; | |
| 529 | GString *pref_name_full; | |
| 530 | GList *tmp; | |
| 3366 | 531 | |
| 5440 | 532 | if(strcmp(element_name, "pref")) |
| 533 | return; | |
| 3500 | 534 | |
| 5440 | 535 | for(i = 0; attribute_names[i]; i++) { |
| 536 | if(!strcmp(attribute_names[i], "name")) { | |
| 537 | pref_name = attribute_values[i]; | |
| 538 | } else if(!strcmp(attribute_names[i], "type")) { | |
| 539 | if(!strcmp(attribute_values[i], "bool")) | |
| 540 | pref_type = GAIM_PREF_BOOLEAN; | |
| 541 | else if(!strcmp(attribute_values[i], "int")) | |
| 542 | pref_type = GAIM_PREF_INT; | |
| 543 | else if(!strcmp(attribute_values[i], "string")) | |
| 544 | pref_type = GAIM_PREF_STRING; | |
| 545 | else | |
| 546 | return; | |
| 547 | } else if(!strcmp(attribute_names[i], "value")) { | |
| 548 | pref_value = attribute_values[i]; | |
| 549 | } | |
| 550 | } | |
|
873
d40eff5fc359
[gaim-migrate @ 883]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
864
diff
changeset
|
551 | |
| 5440 | 552 | if(!pref_name || !strcmp(pref_name, "/")) |
| 553 | return; | |
|
652
dd4ccd3e5c72
[gaim-migrate @ 662]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
619
diff
changeset
|
554 | |
| 5440 | 555 | pref_name_full = g_string_new(pref_name); |
|
652
dd4ccd3e5c72
[gaim-migrate @ 662]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
619
diff
changeset
|
556 | |
|
5529
4a9fd5f1a400
[gaim-migrate @ 5929]
Christian Hammond <chipx86@chipx86.com>
parents:
5458
diff
changeset
|
557 | for(tmp = prefs_stack; tmp; tmp = tmp->next) { |
| 5440 | 558 | pref_name_full = g_string_prepend_c(pref_name_full, '/'); |
| 559 | pref_name_full = g_string_prepend(pref_name_full, tmp->data); | |
| 560 | } | |
| 1170 | 561 | |
| 5440 | 562 | pref_name_full = g_string_prepend_c(pref_name_full, '/'); |
|
1253
f02697a6aada
[gaim-migrate @ 1263]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
563 | |
| 5533 | 564 | switch(pref_type) { |
| 565 | case GAIM_PREF_NONE: | |
| 566 | break; | |
| 567 | case GAIM_PREF_BOOLEAN: | |
| 568 | gaim_prefs_set_bool(pref_name_full->str, atoi(pref_value)); | |
| 569 | break; | |
| 570 | case GAIM_PREF_INT: | |
| 571 | gaim_prefs_set_int(pref_name_full->str, atoi(pref_value)); | |
| 572 | break; | |
| 573 | case GAIM_PREF_STRING: | |
| 574 | gaim_prefs_set_string(pref_name_full->str, pref_value); | |
| 575 | break; | |
| 5440 | 576 | } |
| 1170 | 577 | |
| 5440 | 578 | prefs_stack = g_list_prepend(prefs_stack, g_strdup(pref_name)); |
| 579 | g_string_free(pref_name_full, TRUE); | |
| 1170 | 580 | } |
| 581 | ||
| 5440 | 582 | static void prefs_end_element_handler(GMarkupParseContext *context, |
| 583 | const gchar *element_name, gpointer user_data, GError **error) { | |
| 584 | if(!strcmp(element_name, "pref")) { | |
| 585 | prefs_stack = g_list_delete_link(prefs_stack, prefs_stack); | |
| 586 | } | |
| 1170 | 587 | } |
| 588 | ||
| 5440 | 589 | static GMarkupParser prefs_parser = { |
| 590 | prefs_start_element_handler, | |
| 591 | prefs_end_element_handler, | |
| 592 | NULL, | |
| 593 | NULL, | |
| 594 | NULL | |
| 595 | }; | |
| 1170 | 596 | |
| 5440 | 597 | void gaim_prefs_load() { |
| 598 | gchar *filename = g_build_filename(gaim_user_dir(), "prefs.xml", NULL); | |
| 599 | gchar *contents = NULL; | |
| 600 | gsize length; | |
| 601 | GMarkupParseContext *context; | |
| 602 | GError *error = NULL; | |
|
5314
56ef6a09fb99
[gaim-migrate @ 5686]
Christian Hammond <chipx86@chipx86.com>
parents:
5297
diff
changeset
|
603 | |
| 5534 | 604 | |
| 605 | if(!filename) { | |
| 606 | prefs_is_loaded = TRUE; | |
| 5440 | 607 | return; |
| 5534 | 608 | } |
| 5440 | 609 | |
| 610 | gaim_debug(GAIM_DEBUG_INFO, "prefs", "Reading %s\n", filename); | |
|
5314
56ef6a09fb99
[gaim-migrate @ 5686]
Christian Hammond <chipx86@chipx86.com>
parents:
5297
diff
changeset
|
611 | |
| 5440 | 612 | if(!g_file_get_contents(filename, &contents, &length, &error)) { |
| 613 | gaim_debug(GAIM_DEBUG_ERROR, "prefs", "Error reading prefs: %s\n", | |
| 614 | error->message); | |
| 615 | g_error_free(error); | |
| 5534 | 616 | prefs_is_loaded = TRUE; |
| 5440 | 617 | return; |
| 1170 | 618 | } |
| 619 | ||
| 5440 | 620 | context = g_markup_parse_context_new(&prefs_parser, 0, NULL, NULL); |
| 621 | ||
| 622 | if(!g_markup_parse_context_parse(context, contents, length, NULL)) { | |
| 623 | g_markup_parse_context_free(context); | |
| 624 | g_free(contents); | |
| 5534 | 625 | prefs_is_loaded = TRUE; |
| 5440 | 626 | return; |
| 627 | } | |
| 628 | ||
| 629 | if(!g_markup_parse_context_end_parse(context, NULL)) { | |
| 630 | gaim_debug(GAIM_DEBUG_ERROR, "prefs", "Error parsing %s\n", filename); | |
| 631 | g_markup_parse_context_free(context); | |
| 632 | g_free(contents); | |
| 5534 | 633 | prefs_is_loaded = TRUE; |
| 5440 | 634 | return; |
| 635 | } | |
| 636 | ||
| 637 | g_markup_parse_context_free(context); | |
| 638 | g_free(contents); | |
| 639 | ||
| 640 | gaim_debug(GAIM_DEBUG_INFO, "prefs", "Finished reading %s\n", filename); | |
| 641 | g_free(filename); | |
| 5534 | 642 | prefs_is_loaded = TRUE; |
|
1006
fb2f2a403962
[gaim-migrate @ 1016]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1002
diff
changeset
|
643 | } |
|
fb2f2a403962
[gaim-migrate @ 1016]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1002
diff
changeset
|
644 | |
| 3366 | 645 |