[evolution/gnome-3-8] bbdb plugin cleanups.



commit 74254f5d466efa7d7a1c6fc04b0d13a3d3133de5
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Apr 13 14:26:58 2013 -0400

    bbdb plugin cleanups.
    
    (cherry picked from commit adf8a1bbead09a39ec1b15a164d78a9587ac1734)

 plugins/bbdb/bbdb.c        | 157 +++++++++++++++++++++------------------------
 plugins/bbdb/bbdb.h        |  11 ++--
 plugins/bbdb/gaimbuddies.c | 143 ++++++++++++++++++-----------------------
 3 files changed, 138 insertions(+), 173 deletions(-)
---
diff --git a/plugins/bbdb/bbdb.c b/plugins/bbdb/bbdb.c
index 0d9bac9..3546a75 100644
--- a/plugins/bbdb/bbdb.c
+++ b/plugins/bbdb/bbdb.c
@@ -43,12 +43,8 @@ GtkWidget *bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data
 
 /* For internal use */
 struct bbdb_stuff {
-       EABConfigTargetPrefs *target;
-
        GtkWidget *combo_box;
        GtkWidget *gaim_combo_box;
-       GtkWidget *check;
-       GtkWidget *check_gaim;
 };
 
 /* Static forward declarations */
@@ -112,8 +108,7 @@ bbdb_timeout (gpointer data)
        return data == NULL;
 }
 
-typedef struct
-{
+typedef struct {
        gchar *name;
        gchar *email;
 } todo_struct;
@@ -128,51 +123,55 @@ free_todo_struct (todo_struct *td)
        }
 }
 
-static GSList *todo = NULL;
+static GQueue todo = G_QUEUE_INIT;
 G_LOCK_DEFINE_STATIC (todo);
 
-static gpointer
-bbdb_do_in_thread (gpointer data)
+static void
+todo_queue_clear (void)
 {
-       EBookClient *client = data;
-
-       /* Open the addressbook */
-       if (client == NULL) {
-               G_LOCK (todo);
-
-               g_slist_foreach (todo, (GFunc) free_todo_struct, NULL);
-               g_slist_free (todo);
-               todo = NULL;
+       G_LOCK (todo);
+       while (!g_queue_is_empty (&todo))
+               free_todo_struct (g_queue_pop_head (&todo));
+       G_UNLOCK (todo);
+}
 
-               G_UNLOCK (todo);
-               return NULL;
-       }
+static todo_struct *
+todo_queue_pop (void)
+{
+       todo_struct *td;
 
        G_LOCK (todo);
-       while (todo) {
-               todo_struct *td = todo->data;
+       td = g_queue_pop_head (&todo);
+       G_UNLOCK (todo);
 
-               todo = g_slist_remove (todo, td);
+       return td;
+}
+
+static gpointer
+todo_queue_process_thread (gpointer data)
+{
+       EBookClient *client = data;
 
-               G_UNLOCK (todo);
+       if (client != NULL) {
+               todo_struct *td;
 
-               if (td) {
+               while ((td = todo_queue_pop ()) != NULL) {
                        bbdb_do_it (client, td->name, td->email);
                        free_todo_struct (td);
                }
 
-               G_LOCK (todo);
-       }
-       G_UNLOCK (todo);
+               g_object_unref (client);
 
-       g_object_unref (client);
+       } else {
+               todo_queue_clear ();
+       }
 
        return NULL;
 }
 
 static void
-bbdb_do_thread (const gchar *name,
-                const gchar *email)
+todo_queue_process (const gchar *name,
+                    const gchar *email)
 {
        todo_struct *td;
 
@@ -184,68 +183,44 @@ bbdb_do_thread (const gchar *name,
        td->email = g_strdup (email);
 
        G_LOCK (todo);
-       if (todo) {
-               /* the list isn't empty, which means there is a thread taking
-                * care of that, thus just add it to the queue */
-               todo = g_slist_append (todo, td);
-       } else {
-               GThread *thread;
-               GError *error = NULL;
-               EBookClient *client = bbdb_create_book_client (AUTOMATIC_CONTACTS_ADDRESSBOOK);
 
-               /* list was empty, add item and create a thread */
-               todo = g_slist_append (todo, td);
-               thread = g_thread_try_new (NULL, bbdb_do_in_thread, client, &error);
+       g_queue_push_tail (&todo, td);
 
-               if (error) {
-                       g_warning ("%s: Creation of the thread failed with error: %s", G_STRFUNC, 
error->message);
-                       g_error_free (error);
+       if (g_queue_get_length (&todo) == 1) {
+               GThread *thread;
+               EBookClient *client;
 
-                       G_UNLOCK (todo);
-                       bbdb_do_in_thread (client);
-                       G_LOCK (todo);
-               } else {
-                       g_thread_unref (thread);
-               }
+               client = bbdb_create_book_client (AUTOMATIC_CONTACTS_ADDRESSBOOK);
+               thread = g_thread_new (NULL, todo_queue_process_thread, client);
+               g_thread_unref (thread);
        }
        G_UNLOCK (todo);
 }
 
 static void
-walk_destinations_and_free (EDestination **dests)
+handle_destination (EDestination *destination)
 {
-       const gchar *name, *addr;
-       gint i;
-
-       if (!dests)
-               return;
+       g_return_if_fail (destination != NULL);
 
-       for (i = 0; dests[i] != NULL; i++) {
-               if (e_destination_is_evolution_list (dests[i])) {
-                       const GList *members;
+       if (e_destination_is_evolution_list (destination)) {
+               GList *list, *link;
 
-                       for (members = e_destination_list_get_dests (dests[i]); members; members = 
members->next) {
-                               const EDestination *member = members->data;
+               /* XXX e_destination_list_get_dests() misuses const. */
+               list = (GList *) e_destination_list_get_dests (destination);
 
-                               if (!member)
-                                       continue;
+               for (link = list; link != NULL; link = g_list_next (link))
+                       handle_destination (E_DESTINATION (link->data));
 
-                               name = e_destination_get_name (member);
-                               addr = e_destination_get_email (member);
+       } else {
+               const gchar *name;
+               const gchar *email;
 
-                               if (name || addr)
-                                       bbdb_do_thread (name, addr);
-                       }
-               } else {
-                       name = e_destination_get_name (dests[i]);
-                       addr = e_destination_get_email (dests[i]);
+               name = e_destination_get_name (destination);
+               email = e_destination_get_email (destination);
 
-                       if (name || addr)
-                               bbdb_do_thread (name, addr);
-               }
+               if (name != NULL || email != NULL)
+                       todo_queue_process (name, email);
        }
-
-       e_destination_freev (dests);
 }
 
 void
@@ -253,6 +228,7 @@ bbdb_handle_send (EPlugin *ep,
                   EMEventTargetComposer *target)
 {
        EComposerHeaderTable *table;
+       EDestination **destinations;
        GSettings *settings;
        gboolean enable;
 
@@ -264,11 +240,26 @@ bbdb_handle_send (EPlugin *ep,
                return;
 
        table = e_msg_composer_get_header_table (target->composer);
-       g_return_if_fail (table);
 
        /* read information from the composer, not from a generated message */
-       walk_destinations_and_free (e_composer_header_table_get_destinations_to (table));
-       walk_destinations_and_free (e_composer_header_table_get_destinations_cc (table));
+
+       destinations = e_composer_header_table_get_destinations_to (table);
+       if (destinations != NULL) {
+               gint ii;
+
+               for (ii = 0; destinations[ii] != NULL; ii++)
+                       handle_destination (destinations[ii]);
+               e_destination_freev (destinations);
+       }
+
+       destinations = e_composer_header_table_get_destinations_cc (table);
+       if (destinations != NULL) {
+               gint ii;
+
+               for (ii = 0; destinations[ii] != NULL; ii++)
+                       handle_destination (destinations[ii]);
+               e_destination_freev (destinations);
+       }
 }
 
 static void
@@ -610,7 +601,6 @@ bbdb_page_factory (EPlugin *ep,
                    EConfigHookItemFactoryData *hook_data)
 {
        struct bbdb_stuff *stuff;
-       EABConfigTargetPrefs *target = (EABConfigTargetPrefs *) hook_data->config->target;
        GtkWidget *page;
        GtkWidget *tab_label;
        GtkWidget *frame;
@@ -630,7 +620,6 @@ bbdb_page_factory (EPlugin *ep,
 
        /* A structure to pass some stuff around */
        stuff = g_new0 (struct bbdb_stuff, 1);
-       stuff->target = target;
 
        /* Create a new notebook page */
        page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
@@ -665,7 +654,6 @@ bbdb_page_factory (EPlugin *ep,
                check, "toggled",
                G_CALLBACK (enable_toggled_cb), stuff);
        gtk_box_pack_start (GTK_BOX (inner_vbox), check, FALSE, FALSE, 0);
-       stuff->check = check;
 
        label = gtk_label_new (_("Select Address book for Automatic Contacts"));
        gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0);
@@ -705,7 +693,6 @@ bbdb_page_factory (EPlugin *ep,
                check_gaim, "toggled",
                G_CALLBACK (enable_gaim_toggled_cb), stuff);
        gtk_box_pack_start (GTK_BOX (inner_vbox), check_gaim, FALSE, FALSE, 0);
-       stuff->check_gaim = check_gaim;
 
        gaim_label = gtk_label_new (_("Select Address book for Pidgin buddy list"));
        gtk_box_pack_start (GTK_BOX (inner_vbox), gaim_label, FALSE, FALSE, 0);
diff --git a/plugins/bbdb/bbdb.h b/plugins/bbdb/bbdb.h
index 6759921..045f80c 100644
--- a/plugins/bbdb/bbdb.h
+++ b/plugins/bbdb/bbdb.h
@@ -40,14 +40,11 @@
 #include <libebook/libebook.h>
 
 /* bbdb.c */
-/* creates an EBookClient for a given type (gaim or contacts), but doesn't open it;
- * this function should be called in a main thread. */
-EBookClient *bbdb_create_book_client (gint type);
-
-gboolean bbdb_check_gaim_enabled (void);
+EBookClient *  bbdb_create_book_client         (gint type);
+gboolean       bbdb_check_gaim_enabled         (void);
 
 /* gaimbuddies.c */
-void bbdb_sync_buddy_list (void);
-void bbdb_sync_buddy_list_check (void);
+void           bbdb_sync_buddy_list            (void);
+void           bbdb_sync_buddy_list_check      (void);
 
 #endif /* __BBDB_H__ */
diff --git a/plugins/bbdb/gaimbuddies.c b/plugins/bbdb/gaimbuddies.c
index 9ef3db2..7951210 100644
--- a/plugins/bbdb/gaimbuddies.c
+++ b/plugins/bbdb/gaimbuddies.c
@@ -59,16 +59,27 @@ typedef struct {
 static gboolean        bbdb_merge_buddy_to_contact     (EBookClient *client,
                                                 GaimBuddy *buddy,
                                                 EContact *contact);
-static GList * bbdb_get_gaim_buddy_list        (void);
+static void    bbdb_get_gaim_buddy_list        (GQueue *out_buddies);
 static gchar * get_node_text                   (xmlNodePtr node);
 static gchar * get_buddy_icon_from_setting     (xmlNodePtr setting);
-static void    free_buddy_list                 (GList *blist);
 static void    parse_buddy_group               (xmlNodePtr group,
-                                                GList **buddies,
+                                                GQueue *out_buddies,
                                                 GSList *blocked);
 static EContactField
                proto_to_contact_field          (const gchar *proto);
 
+static void
+free_gaim_body (GaimBuddy *gb)
+{
+       if (gb != NULL) {
+               g_free (gb->icon);
+               g_free (gb->alias);
+               g_free (gb->account_name);
+               g_free (gb->proto);
+               g_free (gb);
+       }
+}
+
 static gchar *
 get_buddy_filename (void)
 {
@@ -185,24 +196,27 @@ store_last_sync_idle_cb (gpointer data)
 static gboolean syncing = FALSE;
 G_LOCK_DEFINE_STATIC (syncing);
 
-struct sync_thread_data
-{
-       GList *blist;
+struct sync_thread_data {
+       GQueue *buddies;
        EBookClient *client;
 };
 
 static gpointer
 bbdb_sync_buddy_list_in_thread (gpointer data)
 {
-       GList *l;
        struct sync_thread_data *std = data;
+       GList *head, *link;
 
        g_return_val_if_fail (std != NULL, NULL);
 
        printf ("bbdb: Synchronizing buddy list to contacts...\n");
+
        /* Walk the buddy list */
-       for (l = std->blist; l != NULL; l = l->next) {
-               GaimBuddy *b = l->data;
+
+       head = g_queue_peek_head_link (std->buddies);
+
+       for (link = head; link != NULL; link = g_list_next (link)) {
+               GaimBuddy *b = link->data;
                EBookQuery *query;
                gchar *query_string, *uid;
                GSList *contacts = NULL;
@@ -272,7 +286,7 @@ bbdb_sync_buddy_list_in_thread (gpointer data)
                if (!e_book_client_add_contact_sync (std->client, c, &uid, NULL, &error)) {
                        g_warning ("bbdb: Failed to add new contact: %s", error->message);
                        g_error_free (error);
-                       goto finish;
+                       goto exit;
                }
 
                g_object_unref (c);
@@ -281,11 +295,11 @@ bbdb_sync_buddy_list_in_thread (gpointer data)
 
        g_idle_add (store_last_sync_idle_cb, NULL);
 
- finish:
+exit:
        printf ("bbdb: Done syncing buddy list to contacts.\n");
 
        g_object_unref (std->client);
-       free_buddy_list (std->blist);
+       g_queue_free_full (std->buddies, (GDestroyNotify) free_gaim_body);
        g_free (std);
 
        G_LOCK (syncing);
@@ -298,11 +312,7 @@ bbdb_sync_buddy_list_in_thread (gpointer data)
 void
 bbdb_sync_buddy_list (void)
 {
-       GList *blist;
-       GThread *thread;
-       GError *error = NULL;
-       EBookClient *client = NULL;
-       struct sync_thread_data *std;
+       GQueue *buddies;
 
        G_LOCK (syncing);
        if (syncing) {
@@ -311,39 +321,33 @@ bbdb_sync_buddy_list (void)
                return;
        }
 
-       /* Get the Gaim buddy list */
-       blist = bbdb_get_gaim_buddy_list ();
-       if (blist == NULL) {
-               G_UNLOCK (syncing);
-               return;
-       }
-
-       /* Open the addressbook */
-       client = bbdb_create_book_client (GAIM_ADDRESSBOOK);
-       if (client == NULL) {
-               free_buddy_list (blist);
-               G_UNLOCK (syncing);
-               return;
-       }
-
-       std = g_new0 (struct sync_thread_data, 1);
-       std->blist = blist;
-       std->client = client;
-
-       syncing = TRUE;
+       buddies = g_queue_new ();
+       bbdb_get_gaim_buddy_list (buddies);
 
-       thread = g_thread_try_new (NULL, bbdb_sync_buddy_list_in_thread, std, &error);
-       if (error) {
-               g_warning (
-                       "%s: Creation of the thread failed with error: %s",
-                       G_STRFUNC, error->message);
-               g_error_free (error);
-
-               G_UNLOCK (syncing);
-               bbdb_sync_buddy_list_in_thread (std);
-               G_LOCK (syncing);
+       if (g_queue_is_empty (buddies)) {
+               g_queue_free (buddies);
        } else {
-               g_thread_unref (thread);
+               GThread *thread;
+               EBookClient *client;
+
+               /* Open the addressbook */
+               client = bbdb_create_book_client (GAIM_ADDRESSBOOK);
+               if (client != NULL) {
+                       struct sync_thread_data *std;
+
+                       std = g_new0 (struct sync_thread_data, 1);
+                       std->buddies = buddies;
+                       std->client = client;
+
+                       syncing = TRUE;
+
+                       thread = g_thread_new (
+                               NULL, bbdb_sync_buddy_list_in_thread, std);
+                       g_thread_unref (thread);
+               } else {
+                       g_queue_free_full (
+                               buddies, (GDestroyNotify) free_gaim_body);
+               }
        }
 
        G_UNLOCK (syncing);
@@ -466,13 +470,12 @@ get_all_blocked (xmlNodePtr node,
        }
 }
 
-static GList *
-bbdb_get_gaim_buddy_list (void)
+static void
+bbdb_get_gaim_buddy_list (GQueue *out_buddies)
 {
        gchar *blist_path;
        xmlDocPtr buddy_xml;
        xmlNodePtr root, child, blist;
-       GList *buddies = NULL;
        GSList *blocked = NULL;
 
        blist_path = get_buddy_filename ();
@@ -481,14 +484,14 @@ bbdb_get_gaim_buddy_list (void)
        g_free (blist_path);
        if (!buddy_xml) {
                fprintf (stderr, "bbdb: Could not open Pidgin buddy list.\n");
-               return NULL;
+               return;
        }
 
        root = xmlDocGetRootElement (buddy_xml);
        if (strcmp ((const gchar *) root->name, "purple")) {
                fprintf (stderr, "bbdb: Could not parse Pidgin buddy list.\n");
                xmlFreeDoc (buddy_xml);
-               return NULL;
+               return;
        }
 
        for (child = root->children; child != NULL; child = child->next) {
@@ -510,40 +513,18 @@ bbdb_get_gaim_buddy_list (void)
                        stderr, "bbdb: Could not find 'blist' "
                        "element in Pidgin buddy list.\n");
                xmlFreeDoc (buddy_xml);
-               return NULL;
+               return;
        }
 
        for (child = blist->children; child != NULL; child = child->next) {
                if (!strcmp ((const gchar *) child->name, "group"))
-                       parse_buddy_group (child, &buddies, blocked);
+                       parse_buddy_group (child, out_buddies, blocked);
        }
 
        xmlFreeDoc (buddy_xml);
 
        g_slist_foreach (blocked, (GFunc) g_free, NULL);
        g_slist_free (blocked);
-
-       return buddies;
-}
-
-static void
-free_gaim_body (GaimBuddy *gb)
-{
-       if (!gb)
-               return;
-
-       g_free (gb->icon);
-       g_free (gb->alias);
-       g_free (gb->account_name);
-       g_free (gb->proto);
-       g_free (gb);
-}
-
-static void
-free_buddy_list (GList *blist)
-{
-       g_list_foreach (blist, (GFunc) free_gaim_body, NULL);
-       g_list_free (blist);
 }
 
 static gchar *
@@ -575,7 +556,7 @@ get_buddy_icon_from_setting (xmlNodePtr setting)
 
 static void
 parse_contact (xmlNodePtr contact,
-               GList **buddies,
+               GQueue *out_buddies,
                GSList *blocked)
 {
        xmlNodePtr  child;
@@ -625,12 +606,12 @@ parse_contact (xmlNodePtr contact,
        if (is_blocked)
                free_gaim_body (gb);
        else
-               *buddies = g_list_prepend (*buddies, gb);
+               g_queue_push_tail (out_buddies, gb);
 }
 
 static void
 parse_buddy_group (xmlNodePtr group,
-                   GList **buddies,
+                   GQueue *out_buddies,
                    GSList *blocked)
 {
        xmlNodePtr child;
@@ -639,6 +620,6 @@ parse_buddy_group (xmlNodePtr group,
                if (strcmp ((const gchar *) child->name, "contact"))
                        continue;
 
-               parse_contact (child, buddies, blocked);
+               parse_contact (child, out_buddies, blocked);
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]