GnuCash 2.4.99
gnc-gconf-utils.c
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines