|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * gnc-gconf-utils.c -- utility functions for storing/retrieving * 00003 * data in the GConf database for GnuCash * 00004 * Copyright (C) 2005,2006 David Hampton <hampton@employees.org> * 00005 * * 00006 * This program is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU General Public License as * 00008 * published by the Free Software Foundation; either version 2 of * 00009 * the License, or (at your option) any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License* 00017 * along with this program; if not, contact: * 00018 * * 00019 * Free Software Foundation Voice: +1-617-542-5942 * 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00021 * Boston, MA 02110-1301, USA gnu@gnu.org * 00022 * * 00023 \********************************************************************/ 00024 00025 #include "config.h" 00026 00027 #include <stdio.h> 00028 #include <string.h> 00029 #include "gnc-main.h" 00030 #include "gnc-gconf-utils.h" 00031 00032 #define CLIENT_TAG "%s-%s-client" 00033 #define NOTIFY_TAG "%s-%s-notify_id" 00034 00035 static GConfClient *our_client = NULL; 00036 static guint gconf_general_cb_id = 0; 00037 00038 /************************************************************/ 00039 /* Enum Utilities */ 00040 /************************************************************/ 00041 00042 const gchar * 00043 gnc_enum_to_nick(GType type, 00044 gint value) 00045 { 00046 GEnumClass *enum_class; 00047 GEnumValue *enum_value; 00048 00049 /* Lookup the enum in the glib type system */ 00050 enum_class = g_type_class_ref (type); 00051 if (!enum_class) 00052 { 00053 /* g_type_class_ref has already printed a warning. */ 00054 return NULL; 00055 } 00056 00057 enum_value = g_enum_get_value (enum_class, value); 00058 if (!enum_value) 00059 { 00060 /* Use the first item in the enum */ 00061 enum_value = g_enum_get_value (enum_class, 0); 00062 } 00063 return enum_value->value_nick; 00064 } 00065 00066 gint 00067 gnc_enum_from_nick(GType type, 00068 const gchar *name, 00069 gint default_value) 00070 { 00071 GEnumClass *enum_class; 00072 GEnumValue *enum_value; 00073 gchar *alt_name, *ptr; 00074 00075 if (name == NULL) 00076 return default_value; 00077 00078 /* Lookup the enum class in the glib type system */ 00079 enum_class = g_type_class_ref (type); 00080 if (!enum_class) 00081 { 00082 /* g_type_class_ref has already printed a warning. */ 00083 return default_value; 00084 } 00085 00086 /* Lookup the specified enum in the class */ 00087 enum_value = g_enum_get_value_by_nick(enum_class, name); 00088 if (enum_value) 00089 return enum_value->value; 00090 00091 /* Flip '-' and '_' and try again */ 00092 alt_name = g_strdup(name); 00093 if ((ptr = strchr(alt_name, '-')) != NULL) 00094 { 00095 do 00096 { 00097 *ptr++ = '_'; 00098 } 00099 while ((ptr = strchr(ptr, '-')) != NULL); 00100 } 00101 else if ((ptr = strchr(alt_name, '_')) != NULL) 00102 { 00103 do 00104 { 00105 *ptr++ = '-'; 00106 } 00107 while ((ptr = strchr(ptr, '_')) != NULL); 00108 } 00109 else 00110 { 00111 g_free(alt_name); 00112 return default_value; 00113 } 00114 00115 /* Lookup the specified enum in the class */ 00116 enum_value = g_enum_get_value_by_nick(enum_class, alt_name); 00117 g_free(alt_name); 00118 if (enum_value) 00119 return enum_value->value; 00120 return default_value; 00121 } 00122 00123 /************************************************************/ 00124 /* Notification of "General" Section Changes */ 00125 /************************************************************/ 00126 00127 static GOnce gcb_init_once = G_ONCE_INIT; 00128 static GHashTable *gcb_callback_hash = NULL; 00129 static GHookList *gcb_final_hook_list = NULL; 00130 00131 static gpointer 00132 gcb_init (gpointer unused) 00133 { 00134 gcb_callback_hash = g_hash_table_new(g_str_hash, g_str_equal); 00135 00136 gcb_final_hook_list = g_malloc(sizeof(GHookList)); 00137 g_hook_list_init(gcb_final_hook_list, sizeof(GHook)); 00138 return NULL; 00139 } 00140 00141 static void 00142 gcb_call_hook (GHook *hook, gpointer data) 00143 { 00144 ((GFunc)hook->func)(data, hook->data); 00145 } 00146 00147 static void 00148 gnc_gconf_general_changed (GConfClient *client, 00149 guint cnxn_id, 00150 GConfEntry *entry, 00151 gpointer data) 00152 { 00153 const gchar *key, *key_tail; 00154 GHookList *hook_list; 00155 00156 g_once(&gcb_init_once, gcb_init, NULL); 00157 00158 key = gconf_entry_get_key(entry); 00159 key_tail = strrchr(key, '/'); 00160 if (key_tail != NULL) 00161 { 00162 key_tail++; 00163 } 00164 if (key_tail == NULL) 00165 { 00166 /* Should never happen. */ 00167 g_warning("Malformed key %s:", key); 00168 return; 00169 } 00170 00171 hook_list = g_hash_table_lookup(gcb_callback_hash, key_tail); 00172 if (hook_list != NULL) 00173 g_hook_list_marshal(hook_list, TRUE, gcb_call_hook, entry); 00174 g_hook_list_invoke(gcb_final_hook_list, TRUE); 00175 } 00176 00177 00178 void 00179 gnc_gconf_general_register_cb (const gchar *key, 00180 GncGconfGeneralCb func, 00181 gpointer user_data) 00182 { 00183 GHookList *hook_list; 00184 GHook *hook; 00185 00186 g_once(&gcb_init_once, gcb_init, NULL); 00187 hook_list = g_hash_table_lookup(gcb_callback_hash, key); 00188 if (hook_list == NULL) 00189 { 00190 hook_list = g_malloc(sizeof(GHookList)); 00191 g_hook_list_init(hook_list, sizeof(GHook)); 00192 g_hash_table_insert(gcb_callback_hash, (gpointer)key, hook_list); 00193 } 00194 00195 hook = g_hook_find_func_data(hook_list, TRUE, func, user_data); 00196 if (hook != NULL) 00197 { 00198 return; 00199 } 00200 00201 hook = g_hook_alloc(hook_list); 00202 hook->func = func; 00203 hook->data = user_data; 00204 g_hook_append(hook_list, hook); 00205 } 00206 00207 00208 void 00209 gnc_gconf_general_remove_cb (const gchar *key, 00210 GncGconfGeneralCb func, 00211 gpointer user_data) 00212 { 00213 GHookList *hook_list; 00214 GHook *hook; 00215 00216 g_once(&gcb_init_once, gcb_init, NULL); 00217 hook_list = g_hash_table_lookup(gcb_callback_hash, key); 00218 if (hook_list == NULL) 00219 return; 00220 hook = g_hook_find_func_data(hook_list, TRUE, func, user_data); 00221 if (hook == NULL) 00222 return; 00223 00224 g_hook_destroy_link(hook_list, hook); 00225 if (hook_list->hooks == NULL) 00226 { 00227 g_hash_table_remove(gcb_callback_hash, key); 00228 g_free(hook_list); 00229 } 00230 } 00231 00232 00233 void 00234 gnc_gconf_general_register_any_cb (GncGconfGeneralAnyCb func, 00235 gpointer user_data) 00236 { 00237 GHook *hook; 00238 00239 g_once(&gcb_init_once, gcb_init, NULL); 00240 hook = g_hook_find_func_data(gcb_final_hook_list, TRUE, func, user_data); 00241 if (hook != NULL) 00242 return; 00243 00244 hook = g_hook_alloc(gcb_final_hook_list); 00245 hook->func = func; 00246 hook->data = user_data; 00247 g_hook_append(gcb_final_hook_list, hook); 00248 } 00249 00250 00251 void 00252 gnc_gconf_general_remove_any_cb (GncGconfGeneralAnyCb func, 00253 gpointer user_data) 00254 { 00255 GHook *hook; 00256 00257 g_once(&gcb_init_once, gcb_init, NULL); 00258 hook = g_hook_find_func_data(gcb_final_hook_list, TRUE, func, user_data); 00259 if (hook == NULL) 00260 return; 00261 00262 g_hook_unref(gcb_final_hook_list, hook); 00263 } 00264 00265 00266 /************************************************************/ 00267 /* Gconf Utilities */ 00268 /************************************************************/ 00269 00270 char * 00271 gnc_gconf_section_name (const char *name) 00272 { 00273 if (name == NULL) 00274 { 00275 /* Need to return a newly allocated string */ 00276 return g_strdup(gnc_get_gconf_path()); 00277 } 00278 if (*name == '/') 00279 { 00280 /* Need to return a newly allocated string */ 00281 return g_strdup(name); 00282 } 00283 00284 /* This could (should?) be accomplished with a call to 00285 * gnome_gconf_get_app_settings_relative(), but that would introduce 00286 * a new library dependancy, even though its not a gui library. In 00287 * order to keep this file completely "gnome-free" this approach was 00288 * used. 00289 */ 00290 return g_strjoin("/", gnc_get_gconf_path(), name, NULL); 00291 } 00292 00293 char * 00294 gnc_gconf_schema_section_name (const char *name) 00295 { 00296 if (strncmp(name, "/schemas", sizeof("/schemas")) == 0) 00297 { 00298 /* Need to return a newly allocated string */ 00299 return g_strdup(name); 00300 } 00301 00302 /* This could (should?) be accomplished with a call to 00303 * gnome_gconf_get_app_settings_relative(), but that would introduce 00304 * a new library dependancy, even though its not a gui library. In 00305 * order to keep this file completely "gnome-free" this approach was 00306 * used. 00307 */ 00308 return g_strconcat("/schemas", gnc_get_gconf_path(), "/", name, NULL); 00309 } 00310 00311 static gchar * 00312 gnc_gconf_make_key (const gchar *section, const gchar *name) 00313 { 00314 gchar *section_path, *key; 00315 00316 g_assert ((section != NULL) || (name != NULL)); 00317 00318 if (section == NULL) 00319 { 00320 if (*name == '/') 00321 return g_strdup(name); 00322 return gnc_gconf_section_name(name); 00323 } 00324 00325 if (name == NULL) 00326 { 00327 if (*section == '/') 00328 return g_strdup(section); 00329 return gnc_gconf_section_name(section); 00330 } 00331 00332 if (*section == '/') 00333 { 00334 if (*name == '/') 00335 return g_strjoin(NULL, section, name, NULL); 00336 return g_strjoin("/", section, name, NULL); 00337 } 00338 00339 section_path = gnc_gconf_section_name(section); 00340 key = g_strjoin("/", section_path, name, NULL); 00341 g_free(section_path); 00342 return key; 00343 } 00344 00345 00346 static gchar * 00347 gnc_gconf_make_schema_key (const gchar *section, const gchar *name) 00348 { 00349 gchar *intermediate, *key; 00350 00351 g_assert ((section != NULL) || (name != NULL)); 00352 00353 intermediate = gnc_gconf_make_key(section, name); 00354 key = g_strconcat("/schemas", intermediate, NULL); 00355 g_free(intermediate); 00356 return key; 00357 } 00358 00359 00377 static void 00378 gnc_gconf_load_error (const gchar *key, 00379 GError **caller_error, 00380 GError *error) 00381 { 00382 if (caller_error) 00383 { 00384 g_propagate_error(caller_error, error); 00385 } 00386 else 00387 { 00388 printf("Failed to load key %s: %s", key, error->message); 00389 g_error_free(error); 00390 } 00391 } 00392 00393 00411 static void 00412 gnc_gconf_save_error (const gchar *key, 00413 GError **caller_error, 00414 GError *error) 00415 { 00416 if (caller_error) 00417 { 00418 g_propagate_error(caller_error, error); 00419 } 00420 else if (error) 00421 { 00422 printf("Failed to save key %s: %s", key, error->message); 00423 g_error_free(error); 00424 } 00425 else 00426 { 00427 printf("Failed to save key %s: %s", key, "Unknown error"); 00428 } 00429 } 00430 00431 00432 gboolean 00433 gnc_gconf_get_bool (const gchar *section, 00434 const gchar *name, 00435 GError **caller_error) 00436 { 00437 GError *error = NULL; 00438 gboolean value; 00439 gchar *key; 00440 00441 if (our_client == NULL) 00442 our_client = gconf_client_get_default(); 00443 00444 key = gnc_gconf_make_key(section, name); 00445 value = gconf_client_get_bool(our_client, key, &error); 00446 if (error) 00447 { 00448 gnc_gconf_load_error(key, caller_error, error); 00449 } 00450 g_free(key); 00451 return value; 00452 } 00453 00454 gboolean 00455 gnc_gconf_get_bool_no_error (const gchar *section, 00456 const gchar *name) 00457 { 00458 return gnc_gconf_get_bool(section, name, NULL); 00459 } 00460 00461 void 00462 gnc_gconf_set_bool (const gchar *section, 00463 const gchar *name, 00464 const gboolean value, 00465 GError **caller_error) 00466 { 00467 GError *error = NULL; 00468 gchar *key; 00469 00470 if (our_client == NULL) 00471 our_client = gconf_client_get_default(); 00472 00473 /* Remember whether the column width */ 00474 key = gnc_gconf_make_key(section, name); 00475 if (!gconf_client_set_bool(our_client, key, value, &error)) 00476 { 00477 gnc_gconf_save_error(key, caller_error, error); 00478 } 00479 g_free(key); 00480 } 00481 00482 gint 00483 gnc_gconf_get_int (const gchar *section, 00484 const gchar *name, 00485 GError **caller_error) 00486 { 00487 GError *error = NULL; 00488 gint value; 00489 gchar *key; 00490 00491 if (our_client == NULL) 00492 our_client = gconf_client_get_default(); 00493 00494 key = gnc_gconf_make_key(section, name); 00495 value = gconf_client_get_int(our_client, key, &error); 00496 if (error) 00497 { 00498 gnc_gconf_load_error(key, caller_error, error); 00499 } 00500 g_free(key); 00501 return value; 00502 } 00503 00504 void 00505 gnc_gconf_set_int (const gchar *section, 00506 const gchar *name, 00507 const gint value, 00508 GError **caller_error) 00509 { 00510 GError *error = NULL; 00511 gchar *key; 00512 00513 if (our_client == NULL) 00514 our_client = gconf_client_get_default(); 00515 00516 /* Remember whether the column width */ 00517 key = gnc_gconf_make_key(section, name); 00518 if (!gconf_client_set_int(our_client, key, value, &error)) 00519 { 00520 gnc_gconf_save_error(key, caller_error, error); 00521 } 00522 g_free(key); 00523 } 00524 00525 gdouble 00526 gnc_gconf_get_float (const gchar *section, 00527 const gchar *name, 00528 GError **caller_error) 00529 { 00530 GError *error = NULL; 00531 gdouble value; 00532 gchar *key; 00533 00534 if (our_client == NULL) 00535 our_client = gconf_client_get_default(); 00536 00537 key = gnc_gconf_make_key(section, name); 00538 value = gconf_client_get_float(our_client, key, &error); 00539 if (error) 00540 { 00541 gnc_gconf_load_error(key, caller_error, error); 00542 } 00543 g_free(key); 00544 return value; 00545 } 00546 00547 void 00548 gnc_gconf_set_float (const gchar *section, 00549 const gchar *name, 00550 const gdouble value, 00551 GError **caller_error) 00552 { 00553 GError *error = NULL; 00554 gchar *key; 00555 00556 if (our_client == NULL) 00557 our_client = gconf_client_get_default(); 00558 00559 /* Remember whether the column width */ 00560 key = gnc_gconf_make_key(section, name); 00561 if (!gconf_client_set_float(our_client, key, value, &error)) 00562 { 00563 gnc_gconf_save_error(key, caller_error, error); 00564 } 00565 g_free(key); 00566 } 00567 00568 gchar * 00569 gnc_gconf_get_string (const gchar *section, 00570 const gchar *name, 00571 GError **caller_error) 00572 { 00573 GError *error = NULL; 00574 gchar *value; 00575 gchar *key; 00576 00577 if (our_client == NULL) 00578 our_client = gconf_client_get_default(); 00579 00580 key = gnc_gconf_make_key(section, name); 00581 value = gconf_client_get_string(our_client, key, &error); 00582 if (error) 00583 { 00584 gnc_gconf_load_error(key, caller_error, error); 00585 } 00586 g_free(key); 00587 00588 if (value && strlen(value) == 0) 00589 { 00590 g_free(value); 00591 return NULL; 00592 } 00593 return value; 00594 } 00595 00596 void 00597 gnc_gconf_set_string (const gchar *section, 00598 const gchar *name, 00599 const gchar *value, 00600 GError **caller_error) 00601 { 00602 GError *error = NULL; 00603 gchar *key; 00604 00605 if (our_client == NULL) 00606 our_client = gconf_client_get_default(); 00607 00608 key = gnc_gconf_make_key(section, name); 00609 if (!gconf_client_set_string(our_client, key, value, &error)) 00610 { 00611 gnc_gconf_save_error(key, caller_error, error); 00612 } 00613 g_free(key); 00614 } 00615 00616 GSList * 00617 gnc_gconf_get_list (const gchar *section, 00618 const gchar *name, 00619 GConfValueType list_type, 00620 GError **caller_error) 00621 { 00622 GError *error = NULL; 00623 GSList *value; 00624 gchar *key; 00625 00626 if (our_client == NULL) 00627 our_client = gconf_client_get_default(); 00628 00629 key = gnc_gconf_make_key(section, name); 00630 value = gconf_client_get_list(our_client, key, list_type, &error); 00631 if (error) 00632 { 00633 gnc_gconf_load_error(key, caller_error, error); 00634 } 00635 g_free(key); 00636 return value; 00637 } 00638 00639 void 00640 gnc_gconf_set_list (const gchar *section, 00641 const gchar *name, 00642 GConfValueType list_type, 00643 GSList *value, 00644 GError **caller_error) 00645 { 00646 GError *error = NULL; 00647 gchar *key; 00648 00649 if (our_client == NULL) 00650 our_client = gconf_client_get_default(); 00651 00652 key = gnc_gconf_make_key(section, name); 00653 if (!gconf_client_set_list(our_client, key, list_type, value, &error)) 00654 { 00655 gnc_gconf_save_error(key, caller_error, error); 00656 } 00657 g_free(key); 00658 } 00659 00660 GConfSchema * 00661 gnc_gconf_get_schema (const gchar *section, 00662 const gchar *name, 00663 GError **caller_error) 00664 { 00665 GError *error = NULL; 00666 GConfSchema *value; 00667 gchar *key; 00668 00669 if (our_client == NULL) 00670 our_client = gconf_client_get_default(); 00671 00672 key = gnc_gconf_make_key(section, name); 00673 value = gconf_client_get_schema(our_client, key, &error); 00674 if (error) 00675 { 00676 gnc_gconf_load_error(key, caller_error, error); 00677 } 00678 g_free(key); 00679 return value; 00680 } 00681 00682 GSList * 00683 gnc_gconf_client_all_entries (const gchar *name) 00684 { 00685 GError *error = NULL; 00686 GSList *value; 00687 gchar *section; 00688 00689 if (our_client == NULL) 00690 our_client = gconf_client_get_default(); 00691 00692 section = gnc_gconf_section_name(name); 00693 value = gconf_client_all_entries(our_client, section, &error); 00694 g_free(section); 00695 if (error != NULL) 00696 { 00697 printf("Failed to get list of all gconf keys: %s", error->message); 00698 g_error_free(error); 00699 } 00700 00701 return value; 00702 } 00703 00704 void 00705 gnc_gconf_unset (const gchar *section, 00706 const gchar *name, 00707 GError **caller_error) 00708 { 00709 GError *error = NULL; 00710 gchar *key; 00711 00712 if (our_client == NULL) 00713 our_client = gconf_client_get_default(); 00714 00715 key = gnc_gconf_make_key(section, name); 00716 if (!gconf_client_unset(our_client, key, &error)) 00717 { 00718 if (caller_error) 00719 { 00720 g_propagate_error(caller_error, error); 00721 } 00722 else 00723 { 00724 printf("Failed to unset key %s: %s", key, error->message); 00725 g_error_free(error); 00726 } 00727 } 00728 g_free(key); 00729 } 00730 00731 00732 void 00733 gnc_gconf_unset_dir (const gchar *section, 00734 GError **caller_error) 00735 { 00736 GError *error = NULL; 00737 GSList *entries, *tmp; 00738 const gchar *key; 00739 gchar *dir_key; 00740 00741 if (our_client == NULL) 00742 our_client = gconf_client_get_default(); 00743 00744 dir_key = gnc_gconf_make_key(section, NULL); 00745 entries = gconf_client_all_entries(our_client, dir_key, &error); 00746 g_free(dir_key); 00747 if (error) 00748 { 00749 if (caller_error) 00750 { 00751 g_propagate_error(caller_error, error); 00752 } 00753 else 00754 { 00755 printf("Failed to get directory entries for key %s: %s", 00756 dir_key, error->message); 00757 g_error_free(error); 00758 } 00759 return; 00760 } 00761 00762 for (tmp = entries; tmp; tmp = g_slist_next(tmp)) 00763 { 00764 key = gconf_entry_get_key(tmp->data); 00765 if (!gconf_client_unset(our_client, key, &error)) 00766 { 00767 if (caller_error) 00768 { 00769 g_propagate_error(caller_error, error); 00770 } 00771 else 00772 { 00773 printf("Failed to unset key %s: %s", key, error->message); 00774 g_error_free(error); 00775 } 00776 break; 00777 } 00778 } 00779 00780 g_slist_foreach(entries, (GFunc)gconf_entry_free, NULL); 00781 g_slist_free(entries); 00782 } 00783 00784 00785 void 00786 gnc_gconf_suggest_sync (void) 00787 { 00788 GError *error = NULL; 00789 00790 if (our_client == NULL) 00791 our_client = gconf_client_get_default(); 00792 00793 gconf_client_suggest_sync(our_client, &error); 00794 if (error != NULL) 00795 { 00796 printf("Failed to sync gconf: %s", error->message); 00797 g_error_free(error); 00798 } 00799 } 00800 00801 00802 void 00803 gnc_gconf_add_notification (GObject *object, 00804 const gchar *section, 00805 GConfClientNotifyFunc callback, 00806 const gchar *whoami) 00807 { 00808 GConfClient *client; 00809 GError *error = NULL; 00810 gchar *path, *client_tag, *notify_tag; 00811 guint id; 00812 00813 g_return_if_fail(G_IS_OBJECT(object)); 00814 g_return_if_fail(callback != NULL); 00815 g_return_if_fail(whoami != NULL); 00816 00817 client = gconf_client_get_default(); 00818 path = gnc_gconf_section_name(section); 00819 00820 /* 00821 * First we have to add the directory... 00822 */ 00823 gconf_client_add_dir(client, path, GCONF_CLIENT_PRELOAD_ONELEVEL, &error); 00824 if (error != NULL) 00825 { 00826 printf("Failed to add history section to watched directories in gconf: %s", error->message); 00827 g_error_free(error); 00828 g_object_unref(client); 00829 g_free(path); 00830 return; 00831 } 00832 00833 /* 00834 * Then we can add the notification callback. 00835 */ 00836 id = gconf_client_notify_add(client, path, callback, 00837 object, NULL, &error); 00838 if (error != NULL) 00839 { 00840 printf("Failed to set gconf notify for history section: %s", error->message); 00841 gconf_client_remove_dir(client, path, NULL); 00842 g_error_free(error); 00843 g_object_unref(client); 00844 g_free(path); 00845 return; 00846 } 00847 00848 /* 00849 * Save the values needed to undo this later. 00850 */ 00851 client_tag = g_strdup_printf(CLIENT_TAG, section ? section : "", whoami); 00852 notify_tag = g_strdup_printf(NOTIFY_TAG, section ? section : "", whoami); 00853 g_object_set_data(object, client_tag, client); 00854 g_object_set_data(object, notify_tag, GUINT_TO_POINTER(id)); 00855 g_free(notify_tag); 00856 g_free(client_tag); 00857 g_free(path); 00858 } 00859 00860 00861 guint 00862 gnc_gconf_add_anon_notification (const gchar *section, 00863 GConfClientNotifyFunc callback, 00864 gpointer data) 00865 { 00866 GConfClient *client; 00867 GError *error = NULL; 00868 gchar *path; 00869 guint id; 00870 00871 g_return_val_if_fail(callback != NULL, 0); 00872 00873 client = gconf_client_get_default(); 00874 path = gnc_gconf_section_name(section); 00875 00876 00877 /* 00878 * First we have to add the directory... 00879 */ 00880 gconf_client_add_dir(client, path, GCONF_CLIENT_PRELOAD_ONELEVEL, &error); 00881 if (error != NULL) 00882 { 00883 printf("Failed to add history section to watched directories in gconf: %s", error->message); 00884 g_error_free(error); 00885 g_object_unref(client); 00886 g_free(path); 00887 return 0; 00888 } 00889 00890 /* 00891 * Then we can add the notification callback. 00892 */ 00893 id = gconf_client_notify_add(client, path, callback, 00894 data, NULL, &error); 00895 if (error != NULL) 00896 { 00897 printf("Failed to set gconf notify for history section: %s", error->message); 00898 gconf_client_remove_dir(client, path, NULL); 00899 g_error_free(error); 00900 g_object_unref(client); 00901 g_free(path); 00902 return 0; 00903 } 00904 g_free(path); 00905 return id; 00906 } 00907 00908 00909 void 00910 gnc_gconf_remove_notification (GObject *object, 00911 const gchar *section, 00912 const gchar *whoami) 00913 { 00914 GConfClient *client; 00915 gchar *path, *client_tag, *notify_tag; 00916 guint id; 00917 00918 g_return_if_fail(G_IS_OBJECT(object)); 00919 g_return_if_fail(whoami != NULL); 00920 00921 /* 00922 * Remove any gconf notifications 00923 */ 00924 client_tag = g_strdup_printf(CLIENT_TAG, section ? section : "", whoami); 00925 client = g_object_get_data(object, client_tag); 00926 path = gnc_gconf_section_name(section); 00927 if (client) 00928 { 00929 notify_tag = g_strdup_printf(NOTIFY_TAG, section ? section : "", whoami); 00930 id = GPOINTER_TO_UINT(g_object_get_data(object, notify_tag)); 00931 gconf_client_notify_remove(client, id); 00932 gconf_client_remove_dir(client, path, NULL); 00933 g_object_unref(client); 00934 g_free(notify_tag); 00935 } 00936 g_free(path); 00937 g_free(client_tag); 00938 } 00939 00940 00941 void 00942 gnc_gconf_remove_anon_notification (const gchar *section, 00943 guint cnxn_id) 00944 { 00945 GConfClient *client; 00946 gchar *path; 00947 00948 /* 00949 * Remove any gconf notifications 00950 */ 00951 path = gnc_gconf_section_name(section); 00952 client = gconf_client_get_default(); 00953 if (client) 00954 { 00955 gconf_client_notify_remove(client, cnxn_id); 00956 gconf_client_remove_dir(client, path, NULL); 00957 g_object_unref(client); 00958 } 00959 g_free(path); 00960 } 00961 00962 /* ============================================================== */ 00963 00964 gboolean 00965 gnc_gconf_schemas_found (void) 00966 { 00967 GConfSchema* schema; 00968 GError *err = NULL; 00969 gchar *key; 00970 00971 if (our_client == NULL) 00972 our_client = gconf_client_get_default(); 00973 00974 key = gnc_gconf_make_schema_key(GCONF_GENERAL_REGISTER, "use_theme_colors"); 00975 schema = gconf_client_get_schema(our_client, key, &err); 00976 g_free(key); 00977 if (schema == NULL) 00978 { 00979 return FALSE; 00980 } 00981 gconf_schema_free(schema); 00982 00983 /* Set up convenience callback for general section */ 00984 00985 gconf_general_cb_id = 00986 gnc_gconf_add_anon_notification(GCONF_GENERAL, gnc_gconf_general_changed, 00987 NULL); 00988 return TRUE; 00989 }
1.7.4