soylent r142 - trunk/src



Author: treitter
Date: Sun May 25 17:48:32 2008
New Revision: 142
URL: http://svn.gnome.org/viewvc/soylent?rev=142&view=rev

Log:
make the editor simply scrape the UI contents when saving changes (in an effort to get rid of the messy pending_edits usage); only saves IM and address fields right now (refuses to save other fields for now); spews tons of debug messages, but I need to commit this before it rots any more

Modified:
   trunk/src/eds-utils.c
   trunk/src/eds-utils.h
   trunk/src/soylent-browser-person-view.c
   trunk/src/soylent-browser-person-view.h
   trunk/src/soylent-browser.c
   trunk/src/soylent-browser.h

Modified: trunk/src/eds-utils.c
==============================================================================
--- trunk/src/eds-utils.c	(original)
+++ trunk/src/eds-utils.c	Sun May 25 17:48:32 2008
@@ -28,6 +28,8 @@
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 #include <libebook/e-book.h>
+#include <libebook/e-contact.h>
+#include <libebook/e-vcard.h>
 
 #include "eds-utils.h"
 #include "soylent-utils.h"
@@ -168,17 +170,21 @@
 
   g_return_val_if_fail (e_contact, retval);
   g_return_val_if_fail (E_IS_CONTACT (e_contact), retval);
-  g_return_val_if_fail (field_id >= E_CONTACT_FIELD_FIRST, retval);
-  g_return_val_if_fail (field_id < E_CONTACT_FIELD_LAST, retval);
+  g_return_val_if_fail (E_CONTACT_FIELD_IS_VALID (field_id), retval);
   g_return_val_if_fail (type, retval);
   g_return_val_if_fail (!g_str_equal (type, ""), retval);
   g_return_val_if_fail (abs_num > 0, retval);
   /* value may be NULL */
 
+  g_debug ("passed e_vcard_attr_list_set_value validation");
+  g_debug ("field_id: %d", field_id);
+
   attr_list_head = e_contact_get_attributes (e_contact, field_id);
   if (attr_list_head)
     {
       /* FIXME: there's got to be a cleaner way to do this */
+      /* iterate to the given 'abs_num'th item with the given type in the list
+       */
       for (l = attr_list_head;
            l && (abs_num > 0);
            l = g_list_next (l))
@@ -233,6 +239,130 @@
   return retval;
 }
 
+/* Append a value to an EContact's specific attribute list */
+gboolean
+e_vcard_attr_list_prepend_value (EContact *e_contact, EContactField field_id,
+                                 const gchar *type, const gchar *value)
+{
+  gboolean retval = FALSE;
+  /*
+  GList *l = NULL;
+  GList *attr_node = NULL;
+  */
+  GList *attr_list = NULL;
+  EVCardAttribute *attr = NULL;
+  gchar *attr_name = NULL;
+  /*
+  GList *type_existing = NULL;
+  */
+
+  g_return_val_if_fail (e_contact, retval);
+  g_return_val_if_fail (E_IS_CONTACT (e_contact), retval);
+  g_return_val_if_fail (E_CONTACT_FIELD_IS_VALID (field_id), retval);
+  g_return_val_if_fail (type, retval);
+  g_return_val_if_fail (!g_str_equal (type, ""), retval);
+  g_return_val_if_fail (value, retval);
+  g_return_val_if_fail (!g_str_equal (value, ""), retval);
+
+  g_debug ("\npassed e_vcard_attr_list_prepend_value validation");
+  g_debug ("field_id: %d", field_id);
+  g_debug ("  %s, %d, %s\n", type, field_id, value);
+
+  attr_list = e_contact_get_attributes (e_contact, field_id);
+  /*
+  if (attr_list)
+    {
+    */
+
+#if 0
+      for (l = attr_list_head;
+           l && (abs_num > 0);
+           l = g_list_next (l))
+        {
+          EVCardAttribute *attr_cur = NULL;
+
+          attr_cur = l->data;
+          type_existing = e_vcard_attribute_get_param (attr_cur, EVC_TYPE);
+          /* FIXME: apparently an attribute could have multiple types; handle it
+           * */
+          if (type_existing && g_str_equal (type, type_existing->data))
+            {
+              abs_num--;
+              attr_node = l;
+              attr = attr_cur;
+            }
+        }
+#endif
+
+      /*
+      attr = attr_list_head->data;
+      */
+      g_debug ("field name: %s", e_contact_field_name (field_id));
+      /*
+      attr = e_vcard_attribute_new (NULL, e_contact_field_name (field_id));
+      */
+      /* FIXME: un-hardcode the name (last arg) */
+      attr_name = eds_im_field_id_to_vcard_attr (field_id);
+      attr = e_vcard_attribute_new (NULL, attr_name);
+      e_vcard_attribute_add_value (attr, value);
+      attr_list = g_list_prepend (attr_list, attr);
+      e_contact_set_attributes (e_contact, field_id, attr_list);
+
+      g_free (attr_name);
+
+#if 0
+      /* XXX: the abs_num >= 0 check seems unnecessary */
+      if (attr && abs_num >= 0)
+        {
+#endif
+#if 0
+          if (value && !g_str_equal (value, ""))
+            {
+              /*
+              e_vcard_attribute_remove_values (attr);
+              */
+              e_vcard_attribute_add_value (attr, value);
+            }
+          else
+            {
+              g_debug ("deleting link...");
+              attr_list_head = g_list_delete_link (attr_list_head,
+                                                   attr_node);
+            }
+#endif
+
+          /*
+          e_contact_set_attributes (e_contact, field_id, attr_list);
+          */
+
+          /* FIXME: supposedly we own this -- why does freeing it give us a
+          * double-free segfault? 
+          g_free (attr_list_head);
+          */
+          /*
+          retval = TRUE;
+          */
+#if 0
+        }
+      else
+        {
+          g_warning ("invalid attribute (context, number); skipping changes");
+        }
+#endif
+
+      retval = TRUE;
+      /*
+    }
+  else
+    {
+      g_warning ("unable to get the list of attributes for EContact field ID "
+                 "%d", field_id);
+    }
+    */
+
+  return retval;
+}
+
 /* Set an individual field within an EContactAddress.
  * 
  * Return TRUE for success, FALSE for failure. */
@@ -402,3 +532,113 @@
 
   return retval;
 }
+
+#if 0
+/* Return a vCard attribute name for the given EContactField ID. This string
+ * must not be freed or modified.
+ * Eg, E_CONTACT_IM_AIM -> "X-AIM" */
+const gchar*
+eds_im_field_id_to_vcard_attr (EContactField field_id)
+{
+  gchar *retval = NULL;
+
+  g_return_val_if_fail (E_CONTACT_FIELD_IS_VALID (field_id), retval);
+  /* XXX: kind of ugly; breaks if this ordering changes and prevents us from
+   * supporting Gadu-Gadu */
+  /*
+  g_return_val_if_fail (field_id >= E_CONTACT_IM_AIM, retval);
+  g_return_val_if_fail (field_id <= E_CONTACT_IM_ICQ, retval);
+  */
+
+  /* collapse all the individual IM fields together */
+  /* XXX: pretty ugly too */
+  if ((field_id >= E_CONTACT_IM_AIM_HOME_1)
+      && (field_id <= E_CONTACT_IM_AIM_WORK_3))
+    {
+      field_id = E_CONTACT_IM_AIM;
+    }
+  else if ((field_id >= E_CONTACT_IM_GROUPWISE_HOME_1)
+           && (field_id <= E_CONTACT_IM_GROUPWISE_WORK_3))
+    {
+      field_id = E_CONTACT_IM_GROUPWISE;
+    }
+  else if ((field_id >= E_CONTACT_IM_JABBER_HOME_1)
+           && (field_id <= E_CONTACT_IM_JABBER_WORK_3))
+    {
+      field_id = E_CONTACT_IM_JABBER;
+    }
+  else if ((field_id >= E_CONTACT_IM_YAHOO_HOME_1)
+           && (field_id <= E_CONTACT_IM_YAHOO_WORK_3))
+    {
+      field_id = E_CONTACT_IM_YAHOO;
+    }
+  else if ((field_id >= E_CONTACT_IM_MSN_HOME_1)
+           && (field_id <= E_CONTACT_IM_MSN_WORK_3))
+    {
+      field_id = E_CONTACT_IM_MSN;
+    }
+  else if ((field_id >= E_CONTACT_IM_ICQ_HOME_1)
+           && (field_id <= E_CONTACT_IM_ICQ_WORK_3))
+    {
+      field_id = E_CONTACT_IM_ICQ;
+    }
+
+  switch (field_id)
+    {
+      case E_CONTACT_IM_AIM:
+        retval = EVC_X_AIM;
+      case E_CONTACT_IM_GROUPWISE:
+        retval = EVC_X_GROUPWISE;
+      case E_CONTACT_IM_JABBER:
+        retval = EVC_X_JABBER;
+      case E_CONTACT_IM_YAHOO:
+        retval = EVC_X_YAHOO;
+      case E_CONTACT_IM_MSN:
+        retval = EVC_X_MSN;
+      case E_CONTACT_IM_ICQ:
+        retval = EVC_X_ICQ;
+      case E_CONTACT_IM_GADUGADU:
+        retval = EVC_X_GADUGADU;
+      default:
+        retval = NULL;
+    }
+
+  g_debug ("final attr name: %s", retval);
+
+  return retval;
+}
+#endif
+
+/* Return a newly-allocated vCard attribute name for the given EContactField ID.
+ * Eg, E_CONTACT_IM_AIM -> "X-AIM" */
+gchar*
+eds_im_field_id_to_vcard_attr (EContactField field_id)
+{
+  gchar *retval = NULL;
+  const gchar *field_name = NULL;
+  const gchar *proto_name = NULL;
+  gchar *proto_name_uc = NULL;
+
+  g_return_val_if_fail (E_CONTACT_FIELD_IS_VALID (field_id), retval);
+  /* XXX: kind of ugly; breaks if this ordering changes and prevents us from
+   * supporting Gadu-Gadu */
+  g_return_val_if_fail (field_id >= E_CONTACT_IM_AIM, retval);
+  g_return_val_if_fail (field_id <= E_CONTACT_IM_ICQ, retval);
+
+  field_name = e_contact_field_name (field_id);
+
+  /* format of the field name is "im_<protocol in lower case>" */
+  proto_name = field_name + strlen("im_");
+
+  proto_name_uc = g_ascii_strup (proto_name, -1);
+  retval = g_strdup_printf ("X-%s", proto_name_uc);
+
+  g_debug ("field name: %s", field_name);
+  g_debug ("proto name: %s", proto_name);
+  g_debug ("proto name upper case: %s", proto_name_uc);
+  g_debug ("final attr name: %s", retval);
+
+  g_free (proto_name_uc);
+
+  return retval;
+}

Modified: trunk/src/eds-utils.h
==============================================================================
--- trunk/src/eds-utils.h	(original)
+++ trunk/src/eds-utils.h	Sun May 25 17:48:32 2008
@@ -29,6 +29,9 @@
 #include <libebook/e-book.h>
 #include "soylent-defs.h"
 
+#define E_CONTACT_FIELD_IS_VALID(x) (((x) >= E_CONTACT_FIELD_FIRST) \
+                                      && ((x) < E_CONTACT_FIELD_LAST))
+
 GdkPixbuf* gdk_pixbuf_from_inline_photo (EContactPhoto *photo,
                                          guint icon_width_max,
                                          guint icon_height_max);
@@ -45,6 +48,12 @@
                                       EContactField field_id, const gchar *type,
                                       guint abs_num, const gchar *value);
 
+gboolean e_vcard_attr_list_prepend_value (EContact *e_contact,
+                                          EContactField field_id,
+                                          const gchar *type,
+                                          const gchar *value);
+
 gchar* eds_get_name_file_as_from_full (const gchar *full_name);
+gchar* eds_im_field_id_to_vcard_attr (EContactField field_id);
 
 #endif /* _EDS_UTILS_H_ */

Modified: trunk/src/soylent-browser-person-view.c
==============================================================================
--- trunk/src/soylent-browser-person-view.c	(original)
+++ trunk/src/soylent-browser-person-view.c	Sun May 25 17:48:32 2008
@@ -25,6 +25,16 @@
 #include "soylent-browser-person-view.h"
 #include "soylent-utils.h"
 
+typedef struct pre_save_im_tag pre_save_im_t;
+struct pre_save_im_tag
+{
+  /* one of the CONTEXT_* values */
+  guint context;
+  /* general field (eg, E_CONTACT_IM_JABBER) */
+  EContactField e_contact_field;
+  const gchar *value;
+};
+
 const gchar *CONTEXT_STRS[] = {"home", "work", "other",};
 
 static gboolean soylent_browser_person_view_editor_hide
@@ -74,6 +84,16 @@
                                                        EContact* e_contact,
                                                        const gchar* widget_name,
                                                        const gchar* value);
+/* FIXME: cut this if possible */
+/* TODO: uncomment this once it's complete 
+static gboolean soylent_browser_person_set_im_field
+                                                (SoylentBrowser *browser,
+                                                 EContact *e_contact,
+                                                 EContactField e_contact_field,
+                                                 guint context,
+                                                 const gchar *value);
+*/
+
 static gboolean soylent_browser_person_set_field_email (EContact *e_contact,
                                                         guint email_pos,
                                                         gchar *contents_new);
@@ -98,8 +118,8 @@
                                                        const gchar *param_val);
 
 /* Setup/update sections of the person view UI with latest data from e-d-s */
-static gboolean soylent_browser_person_view_update (SoylentBrowser *browser,
-                                                    SoylentPerson *person);
+gboolean soylent_browser_person_view_update (SoylentBrowser *browser,
+                                             SoylentPerson *person);
 static gboolean soylent_browser_person_view_email_update
                                                       (SoylentBrowser *browser,
                                                        SoylentPerson *person);
@@ -362,15 +382,8 @@
       }
 #else
       {
-        gboolean view_update_retval = FALSE;
-
-        view_update_retval = soylent_browser_person_view_update (browser,
-                                                                 person);
-        if (view_update_retval)
-          {
-            retval = soylent_browser_view_set_mode (browser,
-                                                    SB_PEOPLE_VIEW_MODE_EDIT);
-          }
+        retval = soylent_browser_view_set_mode (browser,
+                                                SB_PEOPLE_VIEW_MODE_EDIT);
       }
 #endif /* HAVE_CONTACTS_APP */
     }
@@ -676,7 +689,6 @@
   gchar *domain = NULL;
   gchar *attr_name = NULL;
   gchar *param_val = NULL;
-  SoylentPerson *person = NULL;
 
   g_return_val_if_fail (user_data, retval);
   /* FIXME: uncomment once SoylentBrowser is a GObject:
@@ -692,6 +704,7 @@
 
   /* Make sure any changes to existing details between editing the new detail
    * and hitting Add don't get lost */
+  /* FIXME: cut: with the new "save everything" model, this is unnecessary */
   soylent_browser_person_view_save_changes (NULL, browser);
 
   if (g_str_equal (domain, "Email"))
@@ -757,9 +770,17 @@
     }
 
   /* Make sure we actually commit these changes back */
+  /* TODO: it would be nice if we could just add these changes to the UI and
+   * rely on the window close to save the changes; it would cut out a call to
+   * eds and avoid the side effect of adding a new detail saving any pending
+   * changes to the other fields */
   if (retval)
     {
+      SoylentPerson *person = NULL;
+
+      /*
       soylent_browser_person_view_save_changes (NULL, browser);
+      */
 
       person = soylent_browser_get_selected_person (browser);
       soylent_browser_person_view_update (browser, person);
@@ -1028,6 +1049,7 @@
   return retval;
 }
 
+#if 0
 /* Save unsaved changes to the person's details
  *
  * Return TRUE for success, FALSE for any failure. */
@@ -1121,6 +1143,339 @@
 
   return retval;
 }
+#endif
+
+/* Save unsaved changes to the person's details
+ *
+ * Return TRUE for success, FALSE for any failure. */
+static gboolean
+soylent_browser_person_view_save_changes (GtkWidget *widget, gpointer user_data)
+{
+  gboolean retval = FALSE;
+  SoylentBrowser *browser = NULL;
+  GladeXML *wtree = NULL;
+  /*
+  GHashTable *edits_pending = NULL;
+  */
+  guint context = CONTEXT_FIRST;
+  EContactField e_contact_field = E_CONTACT_FIELD_FIRST - 1;
+  EContact *e_contact = NULL;
+  GList *pre_save_list_im = NULL;
+  GList *l = NULL;
+
+  g_return_val_if_fail (user_data, retval);
+  /* FIXME: uncomment once SoylentBrowser is a GObject:
+  g_return_val_if_fail (SOYLENT_IS_BROWSER (user_data), retval);
+   */
+
+  browser = (SoylentBrowser*) user_data;
+  wtree = soylent_browser_get_widget_tree (browser);
+
+  /* TODO: make this one of the parameters instead */
+  e_contact = soylent_browser_get_selected_person_e_contact (browser);
+
+  /*
+  edits_pending = soylent_browser_get_edits_pending (browser);
+  if (edits_pending)
+    {
+
+      g_hash_table_foreach_remove
+              (edits_pending,
+               (GHRFunc) soylent_browser_person_apply_edits_from_widgets_switch,
+               browser);
+      */
+
+  /* FIXME FIXME FIXME: for all the multi-value fields, apply all changes at
+   * once via e-d-s' multi-value setting functions, for performance reasons */
+
+  /* FIXME: handle name field */
+  /* FIXME: handle email fields */
+  /* FIXME: handle phone fields */
+  /* FIXME: handle web address fields */
+
+  /* FIXME: build up GList(s) of pre_save_im_t* as necessary for each of
+   * the IM fields, then dump them into the contact all at once. Don't bother
+   * with soylent_browser_person_apply_edits_from_widgets_switch() */
+  for (context = CONTEXT_IM_FIRST; context <= CONTEXT_IM_LAST; context++)
+    {
+      guint im_field_pos = 0;
+      /*
+      e_contact_field = CB_DATA_FIELD_IM;
+      */
+
+      for (im_field_pos = 0;
+           im_field_pos < IM_FIELDS_PER_CONTEXT;
+           im_field_pos++)
+        {
+          GtkHBox *hbox_im = NULL;
+          GtkEntry *entry_im = NULL;
+          gchar *hbox_name = NULL;
+          gchar *label_name = NULL;
+          gchar *entry_name = NULL;
+          /*
+          gchar *pos_str = NULL;
+          */
+
+          hbox_name = g_strdup_printf ("hbox_person_im_%s_%d",
+                                       CONTEXT_STRS[context], im_field_pos + 1);
+          label_name = g_strdup_printf ("label_person_im_%s_%d",
+                                        CONTEXT_STRS[context],
+                                        im_field_pos + 1);
+          entry_name = g_strdup_printf ("entry_person_im_%s_%d",
+                                        CONTEXT_STRS[context],
+                                        im_field_pos + 1);
+          entry_im = GTK_ENTRY (glade_xml_get_widget (wtree, entry_name));
+          /*
+          g_debug ("widget name: '%s'", hbox_name);
+          */
+
+          /*
+          pos_str = g_strdup_printf ("hbox_person_im_%s_%d",
+                                     CONTEXT_STRS[context], im_field_pos);
+                                     */
+
+          /*
+          hbox_im = GTK_HBOX (soylent_browser_get_widget (browser, "hbox", "im",
+                                                          CONTEXT_STRS[context],
+                                                          pos_str));
+                                                          */
+          hbox_im = GTK_HBOX (glade_xml_get_widget (wtree, hbox_name));
+          if (GTK_WIDGET_VISIBLE(hbox_im))
+            {
+              /*
+              gchar *label_str = NULL;
+              */
+              GtkLabel *label = NULL;
+              const gchar *label_text = NULL;
+              gchar *proto_name_lc = NULL;
+              gchar *field_name = NULL;
+              pre_save_im_t *pre_save_im = NULL;
+              gchar *value = NULL;
+
+              /*
+              gchar *widget_name = NULL;
+              */
+
+              /*
+              g_debug ("hbox visible");
+              */
+
+              /* FIXME: factor this code better */
+              /*
+              widget_name = g_strdup_printf ("mail_%s", CONTEXT_STRS[context]);
+              */
+              /*
+              soylent_browser_person_apply_edits_from_widgets_switch
+                                                              (entry_name,
+                                                               &e_contact_field,
+                                                               browser);
+                                                               */
+
+              
+              /* TODO: use this solution instead */
+              /*
+              label_str = g_strstr_len (widget_name, strlen (widget_name),
+                                        "person");
+              label_str = g_strdup_printf ("label_%s", label_str);
+              */
+              label = GTK_LABEL (glade_xml_get_widget (wtree, label_name)); 
+              label_text = gtk_label_get_text (label);
+              proto_name_lc = g_ascii_strdown (label_text, strlen (label_text));
+              field_name = g_strdup_printf ("im_%s", proto_name_lc);
+              /*
+              field = e_contact_field_id (field_name);
+              */
+
+              value = g_strdup (gtk_entry_get_text (entry_im));
+
+              pre_save_im = g_new (pre_save_im_t, 1);
+              pre_save_im->context = context;
+              /* FIXME: actually use the correct IM field, based on proto */
+              pre_save_im->e_contact_field = e_contact_field_id (field_name);
+              pre_save_im->value = value;
+              pre_save_list_im = g_list_prepend (pre_save_list_im, pre_save_im);
+
+              e_contact_set_attributes (e_contact, pre_save_im->e_contact_field,
+                                        NULL);
+
+              /*
+              g_free (widget_name);
+              */
+
+              g_free (proto_name_lc);
+              g_free (field_name);
+              /*
+              g_free (context_str);
+              */
+            }
+          /*
+          else
+            {
+              g_debug ("hbox *in*visible");
+            }
+            */
+
+          /*
+          g_free (pos_str);
+          */
+          g_free (hbox_name);
+          g_free (entry_name);
+          g_free (label_name);
+        }
+    }
+
+  /* FIXME: un-hardcode this; handle all types */
+  /*
+  use eds_im_field_id_to_vcard_attr (field_id)); for the IM fields
+  e_vcard_remove_attributes (e_contact, "X-JABBER");
+  */
+
+  g_debug ("would save these IM fields:");
+  /* Traverse in reverse order to preserve order from the editor */
+  for (l = g_list_last (pre_save_list_im); l; l = g_list_previous (l))
+    {
+      pre_save_im_t *fields_im = NULL;
+
+      fields_im = l->data;
+      g_debug ("  %s, %d, %s", CONTEXT_STRS[fields_im->context],
+               fields_im->e_contact_field, fields_im->value);
+
+      /*
+      BREAK ME
+      soylent_browser_person_set_im_field (browser, e_contact,
+                                           fields_im->e_contact_field,
+                                           fields_im->context,
+                                           fields_im->value);
+                                           */
+
+      if (fields_im->value && !g_str_equal (fields_im->value, ""))
+        {
+          e_vcard_attr_list_prepend_value (e_contact,
+                                           fields_im->e_contact_field,
+                                           CONTEXT_STRS[fields_im->context],
+                                           fields_im->value);
+        }
+    }
+
+  /* FIXME: go through pre_save_list_im and g_free all datas' value field, each
+   * struct */
+
+  g_list_free (pre_save_list_im);
+
+  for (context = CONTEXT_FIRST, e_contact_field = E_CONTACT_FIRST_ADDRESS_ID;
+       (context <= CONTEXT_LAST)
+       && (e_contact_field <= E_CONTACT_LAST_ADDRESS_ID);
+       context++, e_contact_field++)
+    {
+      GtkFrame *frame_mail = NULL;
+
+      frame_mail = GTK_FRAME (soylent_browser_get_widget (browser, "frame",
+                                                          "mail",
+                                                          CONTEXT_STRS[context],
+                                                          NULL));
+      if (GTK_WIDGET_VISIBLE(frame_mail))
+        {
+          gchar *widget_name = NULL;
+
+          /*
+          g_debug ("frame visible");
+          */
+
+          /* FIXME: these are special-cased for mail fields due to the way
+           * soylent_browser_person_apply_edits_from_widgets_switch() works;
+           * un-special-case this */
+          widget_name = g_strdup_printf ("mail_%s", CONTEXT_STRS[context]);
+          soylent_browser_person_apply_edits_from_widgets_switch
+                                                              (widget_name,
+                                                               &e_contact_field,
+                                                               browser);
+          g_free (widget_name);
+        }
+      /*
+      else
+        {
+          g_debug ("frame *in*visible");
+        }
+        */
+
+    }
+
+  /*
+      e_contact = soylent_browser_get_selected_person_e_contact (browser);
+      */
+      if (e_contact)
+        {
+          EBook *e_book = NULL;
+
+          /* TODO: wipe person's fields that we deal with above
+           *      eg, wipe all Email, IM, mail, etc. fields */
+          /* TODO: fill in person's fields with data collected above */
+
+          e_book = soylent_browser_get_e_book (browser);
+          if (e_book)
+            {
+              EBookView *e_book_view = NULL;
+
+              e_book_view = soylent_browser_get_e_book_view (browser);
+              if (e_book_view)
+                {
+                  SoylentPerson *person = NULL;
+
+                  person = soylent_browser_get_person_from_e_contact
+                                                                (browser,
+                                                                  e_contact);
+                  if (person)
+                    {
+                      gboolean commit_retval = FALSE;
+                      GError *error = NULL;
+
+                      commit_retval = e_book_commit_contact (e_book,
+                                                              e_contact,
+                                                              &error);
+                      if (commit_retval)
+                        {
+                          retval = TRUE;
+                        }
+                      else
+                        {
+                          g_warning ("Could not commit changes to address "
+                                     "book: %s",
+                                     error ? error->message : "no error given");
+                          g_clear_error (&error);
+                        }
+                    }
+                  else
+                    {
+                      g_warning ("failed to get SoylentPerson from EContact");
+                    }
+                }
+              else
+                {
+                  g_critical ("failed to get the EBookView for the "
+                              "SoylentBrowser");
+                }
+            }
+          else
+            {
+              g_critical ("failed to get EBook for the SoylentBrowser");
+            }
+        }
+      else
+        {
+          g_warning ("failed to get EContact for the person");
+        }
+      /*
+    }
+  else
+    {
+      g_critical ("failed to get the browser's pending edits hash");
+    }
+    */
+
+  return retval;
+}
+
+
 
 static gboolean
 soylent_browser_person_edit_save_scroll_cb (EBookView *book_view,
@@ -1601,22 +1956,8 @@
           /* If we've found our match */
           if (g_str_equal (e_uid, e_uid_cur))
             {
-              gboolean view_update_retval = FALSE;
-
-              view_update_retval = soylent_browser_person_view_update (browser,
-                                                                       person);
-              if (view_update_retval)
-                {
-                  gboolean set_mode_retval = FALSE;
-
-                  set_mode_retval = soylent_browser_view_set_mode
-                                                    (browser,
-                                                     SB_PEOPLE_VIEW_MODE_EDIT);
-                  if (set_mode_retval)
-                    {
-                      retval = TRUE;
-                    }
-                }
+              retval = soylent_browser_view_set_mode (browser,
+                                                      SB_PEOPLE_VIEW_MODE_EDIT);
             }
         }
     }
@@ -1900,9 +2241,11 @@
 
   if (value && (*((EContactField*) value) == CB_DATA_FIELD_IM))
     {
+      g_debug ("Saving IM field...");
       retval = soylent_browser_person_set_im_field_e_vcard (browser, e_contact,
                                                             widget_name,
                                                             contents_new);
+      g_debug ("\n");
     }
   else
     {
@@ -1962,6 +2305,7 @@
   widget_name = (const gchar*) key;
   e_contact_field = *((EContactField*) value);
 
+  /* format of widget_name is "mail_<context>", so <context> starts at pos. 5 */
   context_str = widget_name + 5;
   e_contact = soylent_browser_get_selected_person_e_contact (browser);
   addr = e_contact_get (e_contact, e_contact_field);
@@ -2054,6 +2398,10 @@
   gchar *context_str = NULL;
   gchar *label_str = NULL;
 
+  g_debug ("in set_im_field_e_vcard()");
+  g_debug ("widget_name: %s", widget_name);
+  g_debug ("value: %s", value);
+
   g_return_val_if_fail (browser, retval);
   /* FIXME: uncomment once SoylentBrowser is a GObject:
   g_return_val_if_fail (SOYLENT_IS_BROWSER (browser), retval);
@@ -2064,6 +2412,8 @@
 
   wtree = soylent_browser_get_widget_tree (browser);
 
+  g_debug ("...passed basic validation");
+
   context_str = (gchar*) CONTEXT_STRS[CONTEXT_WORK];
   label_str = g_strstr_len (widget_name, strlen (widget_name), "person");
   label_str = g_strdup_printf ("label_%s", label_str);
@@ -2093,6 +2443,8 @@
       widget_num = g_ascii_strtoull (g_strrstr (label_str, "_") + 1, NULL, 10);
 
       context_str = g_ascii_strup (context_str, -1);
+      g_debug ("final context: '%s'", context_str);
+      g_debug ("widget_num: '%d'", widget_num);
       e_vcard_attr_list_set_value (e_contact, field, context_str, widget_num,
                                    value);
 
@@ -2107,6 +2459,120 @@
   return retval;
 }
 
+/* FIXME: if this changes it to "" (deletes it), find matching EmpathyContact in
+ * person->contacts_live and unref it, and use an Empathy function to remove
+ * (all instances, initially) of that screen name from your network-stored buddy
+ * lists (eventually, when we connect IM screennames with specific user
+ * accounts, we'll be able to remove them just from the specific account). Also,
+ * we should use/use the equivalent of reference counting - only remove the
+ * screen name if no other people include that screen name for the specific
+ * account. If it doesn't exist, use an Empathy function to add it to the
+ * appropriate account (if there's more than one account for the given service
+ * logged in, add it to the one with context matching the group you have the
+ * person in (if there's more than one valid match or they aren't in a matching
+ * group, or you don't have a matching context, pop open a dialog -- shortcut to
+ * this until we do group/context matching)). Then hook up the
+ * "presence-changed" signal handler, and let the initial presence fetching
+ * update the view, etc. (trigger it if necessary) 
+ *
+ * in other words, adding/editing/removing screen names causes buddy list
+ * contact modifications
+ *
+ * XXX: we probably can't support even most of this by 0.1 */
+
+#if 0
+
+/* TODO: complete and uncomment this  */
+/* Set a person's IM field in their EContact on the contents of a corresponding
+ * widget(s) */
+static gboolean
+soylent_browser_person_set_im_field (SoylentBrowser *browser,
+                                     EContact *e_contact,
+                                     EContactField e_contact_field,
+                                     guint context, const gchar *value)
+{
+  gboolean retval = FALSE;
+  GladeXML *wtree = NULL;
+  /*
+  GtkLabel *label = NULL;
+  const gchar *label_text = NULL;
+  */
+  gchar *proto_name_lc = NULL;
+  gchar *field_name = NULL;
+  EContactField field = 0;
+  gchar *context_str = NULL;
+  gchar *label_str = NULL;
+
+  /*
+  g_debug ("in set_im_field_e_vcard()");
+  g_debug ("widget_name: %s", widget_name);
+  g_debug ("value: %s", value);
+  */
+
+  g_return_val_if_fail (browser, retval);
+  /* FIXME: uncomment once SoylentBrowser is a GObject:
+  g_return_val_if_fail (SOYLENT_IS_BROWSER (browser), retval);
+   */
+  g_return_val_if_fail (e_contact, retval);
+  g_return_val_if_fail (E_IS_CONTACT (e_contact), retval);
+  g_return_val_if_fail (e_contact_field <  E_CONTACT_FIELD_FIRST, retval);
+  g_return_val_if_fail (e_contact_field >= E_CONTACT_FIELD_LAST, retval);
+  g_return_val_if_fail (CONTEXT_IM_IS_VALID (context), retval);
+
+  wtree = soylent_browser_get_widget_tree (browser);
+
+  g_debug ("...passed basic validation");
+
+  context_str = (gchar*) CONTEXT_STRS[context];
+  /*
+  context_str = (gchar*) CONTEXT_STRS[CONTEXT_WORK];
+  label_str = g_strstr_len (widget_name, strlen (widget_name), "person");
+  label_str = g_strdup_printf ("label_%s", label_str);
+  label = GTK_LABEL (glade_xml_get_widget (wtree, label_str)); 
+  label_text = gtk_label_get_text (label);
+  proto_name_lc = g_ascii_strdown (label_text, strlen (label_text));
+  field_name = g_strdup_printf ("im_%s", proto_name_lc);
+  field = e_contact_field_id (field_name);
+  */
+
+  /*
+  context_str = (gchar*) CONTEXT_STRS[CONTEXT_WORK];
+  if (!g_strstr_len (widget_name, strlen (widget_name), context_str))
+    {
+      context_str = (gchar*) CONTEXT_STRS[CONTEXT_HOME];
+      
+      if (!g_strstr_len (widget_name, strlen (widget_name), context_str))
+        {
+          g_warning ("could not find a valid context in the widget name");
+          context_str = NULL;
+        }
+    }
+    */
+
+
+
+  g_warning ("THIS FUNCTION IS NOT COMPLETE");
+
+
+
+  if (context_str)
+    {
+      context_str = g_ascii_strup (context_str, -1);
+      g_debug ("final context: '%s'", context_str);
+      e_vcard_attr_list_prepend_value (e_contact, field, context_str, value);
+
+      retval = TRUE;
+    }
+
+  g_free (label_str);
+  g_free (proto_name_lc);
+  g_free (field_name);
+  g_free (context_str);
+
+  return retval;
+}
+#endif
+
 /* Save an email address for the person being edited
  *
  * Return TRUE for success, FALSE for any failure. */
@@ -2163,8 +2629,7 @@
 
   g_return_val_if_fail (e_contact, retval);
   g_return_val_if_fail (E_IS_CONTACT (e_contact), retval);
-  g_return_val_if_fail (e_contact_field >= E_CONTACT_FIELD_FIRST, retval);
-  g_return_val_if_fail (e_contact_field < E_CONTACT_FIELD_LAST, retval);
+  g_return_val_if_fail (E_CONTACT_FIELD_IS_VALID (e_contact_field), retval);
 
   e_contact_set (e_contact, e_contact_field, (gpointer) contents_new);
 
@@ -2195,7 +2660,7 @@
 /* Update the entire Person View UI section
  *
  * Return TRUE for success, FALSE for any failure. */
-static gboolean
+gboolean
 soylent_browser_person_view_update (SoylentBrowser *browser,
                                     SoylentPerson *person)
 {
@@ -2430,12 +2895,21 @@
       guint context = 0;
       guint proto = 0;
 
+
+      soylent_debug ("\n%s\n", 
+                     e_vcard_to_string (E_VCARD (e_contact),
+                                        EVC_FORMAT_VCARD_30));
+
+
+
       entry_pos[CONTEXT_HOME] = entry_pos[CONTEXT_WORK] = ENTRY_POS_INIT;
       for (proto = E_CONTACT_IM_AIM;
            proto < (E_CONTACT_IM_AIM + PROTO_NUM);
            proto++)
         {
-          for (context = CONTEXT_FIRST; context < CONTEXT_NUM; context++)
+          for (context = CONTEXT_IM_FIRST;
+               context <= CONTEXT_IM_LAST;
+               context++)
             {
               GList *im_attr_list = NULL;
               GList *l = NULL;

Modified: trunk/src/soylent-browser-person-view.h
==============================================================================
--- trunk/src/soylent-browser-person-view.h	(original)
+++ trunk/src/soylent-browser-person-view.h	Sun May 25 17:48:32 2008
@@ -33,6 +33,10 @@
   EContact *e_contact;
 };
 
+/* Updating the widgets in the person editor */
+gboolean soylent_browser_person_view_update (SoylentBrowser *browser,
+                                             SoylentPerson *person);
+
 /* Signal handlers */
 gboolean soylent_browser_person_view_save_finalize_cb (GtkWidget *widget,
                                                        GdkEvent *event,

Modified: trunk/src/soylent-browser.c
==============================================================================
--- trunk/src/soylent-browser.c	(original)
+++ trunk/src/soylent-browser.c	Sun May 25 17:48:32 2008
@@ -1071,6 +1071,8 @@
   browser->view_mode = mode;
   switch (browser->view_mode)
     {
+      SoylentPerson *person = NULL;
+
       case SB_PEOPLE_VIEW_MODE_BROWSE:
         gtk_widget_set_sensitive (btn_detail_add, FALSE);
 
@@ -1080,14 +1082,25 @@
         retval = TRUE;
         break;
       case SB_PEOPLE_VIEW_MODE_EDIT:
-        gtk_widget_show (window_person_view);
-        gtk_widget_show (img_person_view);
 
-        gtk_widget_hide (icon_entry_person);
-        gtk_widget_show (hbox_detail_new);
-        gtk_widget_show (hs_detail_new);
+        /* FIXME: when SoylentPerson is a GObject, check SOYLENT_IS_PERSON */
+        person = soylent_browser_get_selected_person (browser);
+        retval = soylent_browser_person_view_update (browser, person);
 
-        retval = TRUE;
+        if (retval)
+          {
+            gtk_widget_show (window_person_view);
+            gtk_widget_show (img_person_view);
+
+            gtk_widget_hide (icon_entry_person);
+            gtk_widget_show (hbox_detail_new);
+            gtk_widget_show (hs_detail_new);
+          }
+        else
+          {
+            g_warning ("failed to update person's details; not displaying edit "
+                       "window");
+          }
         break;
       default:
         /* the g_return_val_if_fail() mode check above should prevent us from

Modified: trunk/src/soylent-browser.h
==============================================================================
--- trunk/src/soylent-browser.h	(original)
+++ trunk/src/soylent-browser.h	Sun May 25 17:48:32 2008
@@ -76,11 +76,16 @@
 /* XXX: hacky. Is there a better way around this? */
 #define SP_ITER_UNSET 3901
 
+/* FIXME: turn these into enums */
 #define CONTEXT_HOME  0
 #define CONTEXT_WORK  1
 #define CONTEXT_OTHER 2
-#define CONTEXT_FIRST 0
-#define CONTEXT_LAST  2
+#define CONTEXT_FIRST CONTEXT_HOME
+#define CONTEXT_LAST  CONTEXT_OTHER
+#define CONTEXT_IM_FIRST CONTEXT_HOME
+#define CONTEXT_IM_LAST  CONTEXT_WORK
+#define CONTEXT_IM_IS_VALID(x) (   ((x) >= CONTEXT_IM_FIRST)\
+                                && ((x) <= CONTEXT_IM_LAST))
 /* ========================================= */
 
 



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