+2008-04-30 Milan Crha <mcrha@redhat.com>
+
+ ** Part of fix for bug #316390
+
+ * libedataserver/e-categories.h:
+ (e_categories_register_change_listener),
+ (e_categories_unregister_change_listener):
+ * libedataserver/e-categories.c: (EChangedListener),
+ (idle_saver_cb), (finalize_categories), (initialize_categories),
+ (e_categories_set_color_for), (e_categories_set_icon_file_for),
+ (e_categories_register_change_listener), (e_categories_add),
+ (e_categories_unregister_change_listener), (e_categories_remove):
+ New API to support listening for changes in categories.
+
2008-04-23 Rob Bradford <rob@openedhand.com>
* Makefile.am:
{ NULL }
};
+/* ------------------------------------------------------------------------- */
+
+typedef struct {
+ GObject object;
+} EChangedListener;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ void (* changed) (void);
+} EChangedListenerClass;
+
+static GType e_changed_listener_get_type (void);
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint changed_listener_signals[LAST_SIGNAL];
+
+static void
+e_changed_listener_class_init (EChangedListenerClass *klass)
+{
+ changed_listener_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EChangedListenerClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_changed_listener_init (EChangedListener *changed)
+{
+}
+
+G_DEFINE_TYPE (EChangedListener, e_changed_listener, G_TYPE_OBJECT);
+
+/* ------------------------------------------------------------------------- */
+
static gboolean initialized = FALSE;
static GHashTable *categories_table = NULL;
static gboolean save_is_pending = FALSE;
static guint idle_id = 0;
+static EChangedListener *listeners = NULL;
+static gboolean changed = FALSE;
static gchar *
build_categories_filename (void)
g_free (filename);
save_is_pending = FALSE;
+ if (changed)
+ g_signal_emit_by_name (listeners, "changed");
+
+ changed = FALSE;
exit:
idle_id = 0;
return FALSE;
categories_table = NULL;
}
+ if (listeners != NULL) {
+ g_object_unref (listeners);
+ listeners = NULL;
+ }
+
initialized = FALSE;
}
g_str_hash, g_str_equal, g_free,
(GDestroyNotify) free_category_info);
+ listeners = g_object_new (e_changed_listener_get_type (), NULL);
+
g_atexit (finalize_categories);
n_added = load_categories ();
g_hash_table_insert (categories_table, g_strdup (category), cat_info);
+ changed = TRUE;
save_categories ();
}
if (!initialized)
initialize_categories ();
- if (g_hash_table_remove (categories_table, category))
+ if (g_hash_table_remove (categories_table, category)) {
+ changed = TRUE;
save_categories ();
+ }
}
/**
g_free (cat_info->color);
cat_info->color = g_strdup (color);
+ changed = TRUE;
save_categories ();
}
#endif /* EDS_DISABLE_DEPRECATED */
g_free (cat_info->icon_file);
cat_info->icon_file = g_strdup (icon_file);
+ changed = TRUE;
save_categories ();
}
return cat_info->searchable;
}
+
+/**
+ * e_categories_register_change_listener:
+ * @listener: the callback to be called on any category change.
+ * @user_data: used data passed to the @listener when called.
+ *
+ * Registers callback to be called on change of any category.
+ * Pair listener and user_data is used to distinguish between listeners.
+ * Listeners can be unregistered with @e_categories_unregister_change_listener.
+ **/
+void
+e_categories_register_change_listener (GCallback listener, gpointer user_data)
+{
+ if (!initialized)
+ initialize_categories ();
+
+ g_signal_connect (listeners, "changed", listener, user_data);
+}
+
+/**
+ * e_categories_unregister_change_listener:
+ * @listener: Callback to be removed.
+ * @user_data: User data as passed with call to @e_categories_register_change_listener.
+ *
+ * Removes previously registered callback from the list of listeners on changes.
+ * If it was not registered, then does nothing.
+ **/
+void
+e_categories_unregister_change_listener (GCallback listener, gpointer user_data)
+{
+ if (initialized)
+ g_signal_handlers_disconnect_by_func (listeners, listener, user_data);
+}