diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2009-09-21 10:32:33 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2009-09-21 10:33:19 +0800 |
commit | 28de5cf05a31122a72c4c4fe49d958f8ba952c1f (patch) | |
tree | 4b1ddeebeae34a02d36488a51c5eb5e16240773a | |
parent | 5606859f3adc9c8b5b3180cd2711948ef413033a (diff) | |
download | gsoc2013-evolution-28de5cf05a31122a72c4c4fe49d958f8ba952c1f.tar.gz gsoc2013-evolution-28de5cf05a31122a72c4c4fe49d958f8ba952c1f.tar.zst gsoc2013-evolution-28de5cf05a31122a72c4c4fe49d958f8ba952c1f.zip |
Bug 595119 - Crash while trying to add a new category in contact
-rw-r--r-- | e-util/e-categories-config.c | 8 | ||||
-rw-r--r-- | e-util/e-util.c | 70 | ||||
-rw-r--r-- | e-util/e-util.h | 2 | ||||
-rw-r--r-- | modules/addressbook/e-book-shell-view-private.c | 4 | ||||
-rw-r--r-- | modules/addressbook/e-book-shell-view-private.h | 1 | ||||
-rw-r--r-- | modules/calendar/e-cal-shell-view-private.c | 4 | ||||
-rw-r--r-- | modules/calendar/e-memo-shell-view-private.c | 4 | ||||
-rw-r--r-- | modules/calendar/e-task-shell-view-private.c | 4 |
8 files changed, 87 insertions, 10 deletions
diff --git a/e-util/e-categories-config.c b/e-util/e-categories-config.c index 3dc35588b0..1abef79983 100644 --- a/e-util/e-categories-config.c +++ b/e-util/e-categories-config.c @@ -20,12 +20,15 @@ * */ +#include "e-categories-config.h" + #include <string.h> #include <gtk/gtk.h> #include <glib/gi18n.h> #include <libedataserver/e-categories.h> #include <libedataserverui/e-categories-dialog.h> -#include "e-categories-config.h" + +#include "e-util/e-util.h" static GHashTable *pixbufs_cache = NULL; @@ -62,7 +65,8 @@ e_categories_config_get_icon_for (const gchar *category, GdkPixbuf **pixbuf) if (!pixbufs_cache) { pixbufs_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_pixbuf_cb); - e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), NULL); + e_categories_add_change_hook ( + (GHookFunc) categories_changed_cb, NULL); } else { gpointer key = NULL, value = NULL; diff --git a/e-util/e-util.c b/e-util/e-util.c index b2daca96f9..4e954a1c6c 100644 --- a/e-util/e-util.c +++ b/e-util/e-util.c @@ -410,6 +410,76 @@ e_radio_action_get_current_action (GtkRadioAction *radio_action) return NULL; } +/* Helper for e_categories_add_change_hook() */ +static void +categories_changed_cb (GObject *useless_opaque_object, + GHookList *hook_list) +{ + /* e_categories_register_change_listener() is broken because + * it requires callbacks to allow for some opaque GObject as + * the first argument (not does it document this). */ + g_hook_list_invoke (hook_list, FALSE); +} + +/* Helper for e_categories_add_change_hook() */ +static void +categories_weak_notify_cb (GHookList *hook_list, + gpointer where_the_object_was) +{ + GHook *hook; + + /* This should not happen, but if we fail to find the hook for + * some reason, g_hook_destroy_link() will warn about the NULL + * pointer, which is all we would do anyway so no need to test + * for it ourselves. */ + hook = g_hook_find_data (hook_list, TRUE, where_the_object_was); + g_hook_destroy_link (hook_list, hook); +} + +/** + * e_categories_add_change_hook: + * @func: a hook function + * @object: a #GObject to be passed to @func, or %NULL + * + * A saner alternative to e_categories_register_change_listener(). + * + * Adds a hook function to be called when a category is added, removed or + * modified. If @object is not %NULL, the hook function is automatically + * removed when @object is finalized. + **/ +void +e_categories_add_change_hook (GHookFunc func, + gpointer object) +{ + static gboolean initialized = FALSE; + static GHookList hook_list; + GHook *hook; + + g_return_if_fail (func != NULL); + + if (object != NULL) + g_return_if_fail (G_IS_OBJECT (object)); + + if (!initialized) { + g_hook_list_init (&hook_list, sizeof (GHook)); + e_categories_register_change_listener ( + G_CALLBACK (categories_changed_cb), &hook_list); + initialized = TRUE; + } + + hook = g_hook_alloc (&hook_list); + + hook->func = func; + hook->data = object; + + if (object != NULL) + g_object_weak_ref ( + G_OBJECT (object), (GWeakNotify) + categories_weak_notify_cb, &hook_list); + + g_hook_append (&hook_list, hook); +} + /** * e_type_traverse: * @parent_type: the root #GType to traverse from diff --git a/e-util/e-util.h b/e-util/e-util.h index 83b3141232..68abcd4cba 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -61,6 +61,8 @@ void e_action_group_remove_all_actions (GtkActionGroup *action_group); GtkRadioAction *e_radio_action_get_current_action (GtkRadioAction *radio_action); +void e_categories_add_change_hook (GHookFunc func, + gpointer object); void e_type_traverse (GType parent_type, ETypeFunc func, gpointer user_data); diff --git a/modules/addressbook/e-book-shell-view-private.c b/modules/addressbook/e-book-shell-view-private.c index 55a2e8c433..279cf87cf6 100644 --- a/modules/addressbook/e-book-shell-view-private.c +++ b/modules/addressbook/e-book-shell-view-private.c @@ -484,8 +484,8 @@ e_book_shell_view_private_constructed (EBookShellView *book_shell_view) G_CALLBACK (book_shell_view_activate_selected_source), book_shell_view); - e_categories_register_change_listener ( - G_CALLBACK (e_book_shell_view_update_search_filter), + e_categories_add_change_hook ( + (GHookFunc) e_book_shell_view_update_search_filter, book_shell_view); e_book_shell_view_actions_init (book_shell_view); diff --git a/modules/addressbook/e-book-shell-view-private.h b/modules/addressbook/e-book-shell-view-private.h index 8b8da3f4c6..fa8624692a 100644 --- a/modules/addressbook/e-book-shell-view-private.h +++ b/modules/addressbook/e-book-shell-view-private.h @@ -32,6 +32,7 @@ #include <libedataserver/e-sexp.h> #include <libedataserverui/e-source-selector.h> +#include "e-util/e-util.h" #include "e-util/e-binding.h" #include "e-util/gconf-bridge.h" #include "shell/e-shell-content.h" diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c index d88c148bca..98aacb9db7 100644 --- a/modules/calendar/e-cal-shell-view-private.c +++ b/modules/calendar/e-cal-shell-view-private.c @@ -528,8 +528,8 @@ e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view) G_CALLBACK (e_cal_shell_view_taskpad_actions_update), cal_shell_view); - e_categories_register_change_listener ( - G_CALLBACK (e_cal_shell_view_update_search_filter), + e_categories_add_change_hook ( + (GHookFunc) e_cal_shell_view_update_search_filter, cal_shell_view); e_cal_shell_view_actions_init (cal_shell_view); diff --git a/modules/calendar/e-memo-shell-view-private.c b/modules/calendar/e-memo-shell-view-private.c index f1d331fab3..b0a6ee6be1 100644 --- a/modules/calendar/e-memo-shell-view-private.c +++ b/modules/calendar/e-memo-shell-view-private.c @@ -268,8 +268,8 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view) G_CALLBACK (e_shell_view_update_actions), memo_shell_view); - e_categories_register_change_listener ( - G_CALLBACK (e_memo_shell_view_update_search_filter), + e_categories_add_change_hook ( + (GHookFunc) e_memo_shell_view_update_search_filter, memo_shell_view); e_memo_shell_view_actions_init (memo_shell_view); diff --git a/modules/calendar/e-task-shell-view-private.c b/modules/calendar/e-task-shell-view-private.c index 581ad88b47..74dd295bcb 100644 --- a/modules/calendar/e-task-shell-view-private.c +++ b/modules/calendar/e-task-shell-view-private.c @@ -322,8 +322,8 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view) G_CALLBACK (e_shell_view_update_actions), task_shell_view); - e_categories_register_change_listener ( - G_CALLBACK (e_task_shell_view_update_search_filter), + e_categories_add_change_hook ( + (GHookFunc) e_task_shell_view_update_search_filter, task_shell_view); task_shell_view_update_timeout_cb (task_shell_view); |