[evolution-data-server/documentation-effort: 10/18] Cursor Example Code: Improving readability of cursor-data.c, a little.



commit 6a9fb8fda3fabc96e2a339c9fc18fb0e7bc09775
Author: Tristan Van Berkom <tristan upstairslabs com>
Date:   Thu Dec 5 18:13:03 2013 +0900

    Cursor Example Code: Improving readability of cursor-data.c, a little.

 examples/cursor/cursor-data.c |  239 ++++++++++++++++++-----------------------
 1 files changed, 106 insertions(+), 133 deletions(-)
---
diff --git a/examples/cursor/cursor-data.c b/examples/cursor/cursor-data.c
index f7b0996..e24805f 100644
--- a/examples/cursor/cursor-data.c
+++ b/examples/cursor/cursor-data.c
@@ -22,14 +22,12 @@
 
 #define CURSOR_DATA_SOURCE_ID "cursor-example-book"
 
-static void                  load_contacts (EBookClient          *client,
-                                           const gchar          *vcard_directory);
-static EBookClientCursor    *get_cursor    (EBookClient          *book_client);
-
-/* Just an example, we need to spin the main loop
- * a bit to wait for the ESource to be created,
+/* We need to spin the main loop a bit to wait for the ESource
+ * to be created. This particular API is admittedly cumbersome,
+ * hopefully this will be fixed in a later version so that
+ * the ESource can be synchronously created.
  *
- * So lets just use some global variables here
+ * Just an example so lets just use some global variables here...
  */
 static EBookClient *address_book = NULL;
 static ESource     *address_book_source = NULL;
@@ -64,41 +62,100 @@ cursor_data_source_timeout (gpointer user_data)
        return FALSE;
 }
 
+/*
+ * Helper function to load a contact from a vcard file.
+ */
+static EContact *
+contact_from_file (const gchar *vcard_file)
+{
+       EContact *contact;
+       GError *error;
+       gchar *vcard = NULL;
+
+       if (!g_file_get_contents (vcard_file, &vcard, NULL, &error))
+               g_error ("Failed to load vcard: %s", error->message);
+
+       contact = e_contact_new_from_vcard (vcard);
+       g_free (vcard);
+
+       return contact;
+}
+
+/*
+ * Load all the contacts from 'vcard_directory', and add them to 'client'.
+ */
 static void
-setup_custom_book (ESource *scratch)
+load_contacts (EBookClient *client,
+              const gchar *vcard_directory)
+{
+       GDir *dir;
+       GError *error = NULL;
+       const gchar *filename;
+       GSList *contacts = NULL;
+
+       dir = g_dir_open (vcard_directory, 0, &error);
+       if (!dir)
+               g_error ("Failed to open vcard directory '%s': %s", vcard_directory, error->message);
+
+       while ((filename = g_dir_read_name (dir)) != NULL) {
+
+               if (g_str_has_suffix (filename, ".vcf")) {
+                       gchar *fullpath = g_build_filename (vcard_directory, filename, NULL);
+                       EContact *contact;
+
+                       contact = contact_from_file (fullpath);
+                       contacts = g_slist_prepend (contacts, contact);
+
+                       g_free (fullpath);
+               }
+       }
+
+       g_dir_close (dir);
+
+       if (contacts != NULL) {
+
+               if (!e_book_client_add_contacts_sync (client, contacts, NULL, NULL, &error)) {
+
+                       /* If they were already added, ignore the error */
+                       if (g_error_matches (error, E_BOOK_CLIENT_ERROR,
+                                            E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS))
+                               g_clear_error (&error);
+                       else
+                               g_error ("Failed to add test contacts: %s", error->message);
+               }
+       }
+}
+
+/*
+ * Create an EBookClient cursor sorted by family name, and then by given name as
+ * the secondary sort key.
+ */
+static EBookClientCursor *
+get_cursor (EBookClient *book_client)
 {
-       ESourceBackendSummarySetup *setup;
-
-       g_type_ensure (E_TYPE_SOURCE_BACKEND_SUMMARY_SETUP);
-       setup = e_source_get_extension (scratch, E_SOURCE_EXTENSION_BACKEND_SUMMARY_SETUP);
-       e_source_backend_summary_setup_set_summary_fields (
-               setup,
-               E_CONTACT_FULL_NAME,
-               E_CONTACT_FAMILY_NAME,
-               E_CONTACT_GIVEN_NAME,
-               E_CONTACT_NICKNAME,
-               E_CONTACT_TEL,
-               E_CONTACT_EMAIL,
-               0);
-       e_source_backend_summary_setup_set_indexed_fields (
-               setup,
-               E_CONTACT_FULL_NAME, E_BOOK_INDEX_PREFIX,
-               E_CONTACT_FAMILY_NAME, E_BOOK_INDEX_PREFIX,
-               E_CONTACT_GIVEN_NAME, E_BOOK_INDEX_PREFIX,
-               E_CONTACT_NICKNAME, E_BOOK_INDEX_PREFIX,
-               E_CONTACT_TEL, E_BOOK_INDEX_PREFIX,
-               E_CONTACT_TEL, E_BOOK_INDEX_PHONE,
-               E_CONTACT_EMAIL, E_BOOK_INDEX_PREFIX,
-               0);
+  EContactField sort_fields[] = { E_CONTACT_FAMILY_NAME, E_CONTACT_GIVEN_NAME };
+  EBookCursorSortType sort_types[] = { E_BOOK_CURSOR_SORT_ASCENDING, E_BOOK_CURSOR_SORT_ASCENDING };
+  EBookClientCursor *cursor = NULL;
+  GError *error = NULL;
+
+  if (!e_book_client_get_cursor_sync (book_client,
+                                     NULL,
+                                     sort_fields,
+                                     sort_types,
+                                     2,
+                                     &cursor,
+                                     NULL,
+                                     &error)) {
+         g_warning ("Unable to create cursor");
+         g_clear_error (&error);
+  }
+
+  return cursor;
 }
 
-/* This ensures that all of the test contacts are
- * installed in the CURSOR_DATA_SOURCE_ID test book.
- *
- * Then it opens an EBookClientCursor.
- *
- * The cursor has no filter on the results and is
- * ordered by family name (ascending) and then given name (ascending).
+/* Entry point for this file, here we take care of
+ * creating the addressbook if it doesnt exist,
+ * getting an EBookClient, and creating our EBookClientCursor.
  */
 EBookClient *
 cursor_load_data (const gchar        *vcard_path,
@@ -109,12 +166,13 @@ cursor_load_data (const gchar        *vcard_path,
        ESourceBackend *backend = NULL;
        GMainLoop *loop;
        GError  *error = NULL;
-       GSList *contacts = NULL;
        EBookClient *ret_book;
 
        g_return_val_if_fail (vcard_path != NULL, NULL);
        g_return_val_if_fail (ret_cursor != NULL, NULL);
 
+       g_print ("Cursor loading data from %s\n", vcard_path);
+
        loop = g_main_loop_new (NULL, FALSE);
 
        registry = e_source_registry_new_sync (NULL, &error);
@@ -132,8 +190,10 @@ cursor_load_data (const gchar        *vcard_path,
        backend = e_source_get_extension (scratch, E_SOURCE_EXTENSION_ADDRESS_BOOK);
        e_source_backend_set_backend_name (backend, "local");
 
-       /* Setup custom summary fields, so that we can use those fields with the cursor */
-       setup_custom_book (scratch);
+       /* Now is the right time to use the ESourceBackendSummarySetup to configure
+        * your newly created addressbook. This configuration should happen on the
+        * scratch source before calling e_source_registry_commit_source_sync().
+        */
 
        /* Commit the source to the registry */
        if (!e_source_registry_commit_source_sync (registry, scratch, NULL, &error)) {
@@ -155,6 +215,10 @@ cursor_load_data (const gchar        *vcard_path,
 
        g_object_unref (scratch);
 
+       /* Give EDS a little time to actually create the ESource remotely and
+        * also have a copy if it cached locally, wait for the "source-added"
+        * signal.
+        */
        if (address_book == NULL) {
                g_timeout_add_seconds (20, cursor_data_source_timeout, NULL);
                g_main_loop_run (loop);
@@ -166,21 +230,7 @@ cursor_load_data (const gchar        *vcard_path,
        /**********************************************************
         * Ok, done with creating an addressbook, let's add data  *
         **********************************************************/
-
-       /* First check if there are already some contacts, if so then
-        * avoid adding them again
-        */
-       if (!e_book_client_get_contacts_uids_sync (address_book,
-                                                  "", &contacts, NULL, &error))
-               g_error ("Failed to query addressbook for existing contacts");
-
-       if (contacts != NULL) {
-               /* We already have contacts, no need to add them */
-               g_slist_free_full (contacts, (GDestroyNotify)g_free);
-               contacts = NULL;
-       } else {
-               load_contacts (address_book, vcard_path);
-       }
+       load_contacts (address_book, vcard_path);
 
        /* Addressbook should have contacts now, let's create the cursor */
        *ret_cursor = get_cursor (address_book);
@@ -199,80 +249,3 @@ cursor_load_data (const gchar        *vcard_path,
        /* Return the addressbook */
        return ret_book;
 }
-
-static EContact *
-contact_from_file (const gchar *vcard_file)
-{
-       EContact *contact;
-       GError *error;
-       gchar *vcard = NULL;
-
-       if (!g_file_get_contents (vcard_file, &vcard, NULL, &error))
-               g_error ("Failed to load vcard: %s", error->message);
-
-       contact = e_contact_new_from_vcard (vcard);
-       g_free (vcard);
-
-       return contact;
-}
-
-static void
-load_contacts (EBookClient *client,
-              const gchar *vcard_directory)
-{
-       GDir *dir;
-       GError *error = NULL;
-       const gchar *filename;
-       GSList *contacts = NULL;
-
-       dir = g_dir_open (vcard_directory, 0, &error);
-       if (!dir)
-               g_error ("Failed to open vcard directory '%s': %s", vcard_directory, error->message);
-
-       while ((filename = g_dir_read_name (dir)) != NULL) {
-
-               if (g_str_has_suffix (filename, ".vcf")) {
-                       gchar *fullpath = g_build_filename (vcard_directory, filename, NULL);
-                       EContact *contact;
-
-                       g_print ("Loading contact from: %s\n", fullpath);
-
-                       contact = contact_from_file (fullpath);
-                       contacts = g_slist_prepend (contacts, contact);
-
-                       g_free (fullpath);
-               }
-       }
-
-       g_dir_close (dir);
-
-       if (contacts != NULL) {
-
-               if (!e_book_client_add_contacts_sync (client, contacts, NULL, NULL, &error))
-                       g_error ("Failed to add contacts");
-       } else
-               g_error ("No contacts found in vcard directory: %s", vcard_directory);
-}
-
-static EBookClientCursor *
-get_cursor (EBookClient *book_client)
-{
-  EContactField sort_fields[] = { E_CONTACT_FAMILY_NAME, E_CONTACT_GIVEN_NAME };
-  EBookCursorSortType sort_types[] = { E_BOOK_CURSOR_SORT_ASCENDING, E_BOOK_CURSOR_SORT_ASCENDING };
-  EBookClientCursor *cursor = NULL;
-  GError *error = NULL;
-
-  if (!e_book_client_get_cursor_sync (book_client,
-                                     NULL,
-                                     sort_fields,
-                                     sort_types,
-                                     2,
-                                     &cursor,
-                                     NULL,
-                                     &error)) {
-         g_warning ("Unable to create cursor");
-         g_clear_error (&error);
-  }
-
-  return cursor;
-}


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