static ESExpResult *
func_exists_vcard (struct _ESExp *f,
                   gint argc,
                   struct _ESExpResult **argv,
                   gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *r;
	gint truth = FALSE;

	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
		const gchar *attr_name;
		EVCardAttribute *attr;
		GList *values;
		gchar *s;

		attr_name = argv[0]->value.string;
		attr = e_vcard_get_attribute (E_VCARD (ctx->contact), attr_name);
		if (attr) {
			values = e_vcard_attribute_get_values (attr);
			if (g_list_length (values) > 0) {
				s = values->data;
				if (s[0] != '\0') {
					truth = TRUE;
				}
			}
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_BOOL);
	r->value.boolean = truth;

	return r;
}
Пример #2
0
static void
contacts_change_groups_cb (GtkWidget *widget, ContactsGroupChangeData *data)
{
	GList *g, *bools = NULL;
	GList *results = NULL;
	GList *values = e_vcard_attribute_get_values (data->attr);

	for (g = data->contacts_data->contacts_groups; g; g = g->next) {
		if (g_list_find_custom (values, g->data, (GCompareFunc)strcmp))
			bools = g_list_append (bools, GINT_TO_POINTER (TRUE));
		else
			bools = g_list_append (bools, GINT_TO_POINTER (FALSE));
	}
	
	if (contacts_chooser (data->contacts_data, _("Change groups"), _("<b>Choose groups"
		"</b>"), data->contacts_data->contacts_groups, bools, TRUE, TRUE, &results)) {

		gchar *new_groups = results ?
			contacts_string_list_as_string (results, ", ", FALSE) :
			g_strdup ("None");
		g_free (new_groups);

		e_vcard_attribute_remove_values (data->attr);
		for (g = results; g; g = g->next) {
			e_vcard_attribute_add_value (data->attr, g->data);
			if (!g_list_find_custom (data->contacts_data->contacts_groups, g->data, (GCompareFunc) strcmp))
					data->contacts_data->contacts_groups = g_list_prepend (data->contacts_data->contacts_groups, g_strdup (g->data));
		}
		data->contacts_data->changed = TRUE;
	}
}
Пример #3
0
static char *evcard_name_attribute_to_string(EVCard *evcard)
{
	EVCardAttribute *attrib;
	GList *l;
	GString *name = NULL;

	attrib = e_vcard_get_attribute(evcard, EVC_N);
	if (!attrib)
		return NULL;

	for (l = e_vcard_attribute_get_values(attrib); l; l = l->next) {
		const char *value = l->data;

		if (!strlen(value))
			continue;

		if (!name)
			name = g_string_new(value);
		else {
			name = g_string_append(name, ";");
			name = g_string_append(name, l->data);
		}
	}

	if (!name)
		return NULL;

	return g_string_free(name, FALSE);
}
Пример #4
0
/*
 * Strip empty attributes from a vcard
 * Returns: the number of attributes left on the card
 */
gint
hito_vcard_strip_empty_attributes (EVCard *card)
{
  GList *attrs, *values;
  gboolean remove;
  EVCardAttribute *attribute;
  gint count = 0;

  attrs = e_vcard_get_attributes (card);
  while (attrs)
  {
    count++;
    attribute = attrs->data;
    remove = TRUE;
    values = e_vcard_attribute_get_values (attrs->data);

    while (values)
    {
      if (g_utf8_strlen (values->data, -1) > 0)
      {
        remove = FALSE;
        break;
      }
      values = g_list_next (values);
    }

    attrs = g_list_next (attrs);
    if (remove)
    {
      e_vcard_remove_attribute (card, attribute);
      count--;
    }
  }
  return count;
}
/**
 * e_vcard_attribute_get_value:
 * @attr: an #EVCardAttribute
 *
 * Gets the value of a single-valued #EVCardAttribute, @attr.
 *
 * Return value: A newly allocated string representing the value.
 **/
char*
e_vcard_attribute_get_value (EVCardAttribute *attr)
{
	GList *values;

	g_return_val_if_fail (attr != NULL, NULL);

	values = e_vcard_attribute_get_values (attr);

	if (!e_vcard_attribute_is_single_valued (attr))
		g_warning ("e_vcard_attribute_get_value called on multivalued attribute");

	return values ? g_strdup ((char*)values->data) : NULL;
}
Пример #6
0
/*
 * load the attribute value, returning a newly allocated semicolon seperated
 * string for multivalue attributes
 */
gchar*
hito_vcard_attribute_get_value_string (EVCardAttribute *attr)
{
  gchar *attr_value = NULL;
  GList *l;
  l = e_vcard_attribute_get_values (attr);
  if (l)
  {
    attr_value = g_strdup (l->data);

    while ((l = g_list_next (l)))
    {
      gchar *old = attr_value;
      if (old)
        attr_value = g_strdup_printf ("%s; %s", old, (gchar*) l->data);
      else
        attr_value = g_strdup (l->data);
      g_free (old);
    }
  }
  return attr_value;
}
Пример #7
0
gboolean
hito_vcard_attribute_has_value (EVCardAttribute *attr, const gchar *value)
{
  GList *list;
  gboolean result;

  g_return_val_if_fail (attr, FALSE);
  g_return_val_if_fail (value, FALSE);

  result = FALSE;

  list = e_vcard_attribute_get_values (attr);
  while (list)
  {
    if (list->data && g_str_equal (list->data, value))
    {
      result = TRUE;
      break;
    }
    list = g_list_next (list);
  }
  return result;
}
Пример #8
0
/* Calbacks */
static void
moko_contacts_add_contact (MokoContacts *contacts, EContact *e_contact)
{
  MokoContactsPrivate *priv;
  MokoContact *m_contact = NULL;
  const gchar *name, *uid;
  GList *attributes, *params, *numbers;

  g_return_if_fail (MOKO_IS_CONTACTS (contacts));
  g_return_if_fail (E_IS_CONTACT (e_contact));
  priv = contacts->priv;

  uid = e_contact_get_const (e_contact, E_CONTACT_UID);
  if (g_hash_table_lookup (priv->uids, uid))
	  return;
  
  name = e_contact_get_const (e_contact, E_CONTACT_FULL_NAME);
  if (!name || (g_utf8_strlen (name, -1) <= 0))
    name = "Unknown";
  
  /* Create the contact & append to the list */
  m_contact = g_new0 (MokoContact, 1);
  m_contact->name = g_strdup (name);
  m_contact->uid = g_strdup (uid);
  m_contact->photo = NULL;

  priv->contacts = g_list_append (priv->contacts, m_contact);
  g_hash_table_insert (priv->uids,
                       g_strdup (uid), 
                       m_contact);

  /* Now go through the numbers,creating MokoNumber for them */
  for (attributes = e_vcard_get_attributes (E_VCARD(e_contact)); attributes; attributes = attributes->next)
  {
    MokoContactEntry  *entry;
    const gchar *phone;
    const char *attr;

    attr = e_vcard_attribute_get_name (attributes->data);
    if (!strcmp (attr, EVC_TEL))
    {
      for (numbers = e_vcard_attribute_get_values (attributes->data); numbers; numbers = numbers->next)
      {
        phone = numbers->data;
        if (phone)
        {
          entry = g_new0 (MokoContactEntry, 1);

          params = e_vcard_attribute_get_param (attributes->data, "TYPE");
          if (params)
            entry->desc = g_strdup (params->data);

          entry->number = normalize (phone);
          entry->contact = m_contact;

          priv->entries = g_list_append (priv->entries, (gpointer)entry);
          g_hash_table_insert (priv->prefixes, 
                               g_strdup (entry->number), 
                               (gpointer)entry);
          add_number (&priv->start, entry);
        }
      }
    }
  }
}
static ESExpResult *
func_exists (struct _ESExp *f,
             gint argc,
             struct _ESExpResult **argv,
             gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *r;
	gint truth = FALSE;

	if (argc == 1
	    && argv[0]->type == ESEXP_RES_STRING) {
		const gchar *propname;
		struct prop_info *info = NULL;
		gint i;
		gboolean saw_any = FALSE;

		propname = argv[0]->value.string;

		for (i = 0; i < G_N_ELEMENTS (prop_info_table); i++) {
			if (!strcmp (prop_info_table[i].query_prop, propname)) {
				saw_any = TRUE;
				info = &prop_info_table[i];

				if (info->prop_type == PROP_TYPE_NORMAL) {
					const gchar *prop = NULL;
					/* searches where the query's property
					 * maps directly to an ecard property */

					prop = e_contact_get_const (ctx->contact, info->field_id);

					if (prop && *prop)
						truth = TRUE;
				}
				else if (info->prop_type == PROP_TYPE_LIST) {
					/* the special searches that match any of the list elements */
					truth = info->list_compare (ctx->contact, "", NULL, exists_helper);
				}
				else if (info->prop_type == PROP_TYPE_DATE) {
					EContactDate *date;

					date = e_contact_get (ctx->contact, info->field_id);

					if (date) {
						truth = TRUE;
						e_contact_date_free (date);
					}
				} else {
					g_warn_if_reached ();

					saw_any = FALSE;
				}

				break;
			}
		}

		if (!saw_any) {
			/* propname didn't match to any of our known "special" properties,
			 * so try to find if it isn't a real field and if so, then check
			 * against value in this field only */
			EContactField fid = e_contact_field_id (propname);

			if (fid >= E_CONTACT_FIELD_FIRST && fid < E_CONTACT_FIELD_LAST &&
			    e_contact_field_is_string (fid)) {
				const gchar *prop = e_contact_get_const (ctx->contact, fid);

				if (prop && *prop)
					truth = TRUE;
			} else {
				/* is is not a known EContact field, try with EVCard attributes */
				EVCardAttribute *attr;
				GList *l, *values;

				if (fid >= E_CONTACT_FIELD_FIRST && fid < E_CONTACT_FIELD_LAST)
					propname = e_contact_vcard_attribute (fid);

				attr = e_vcard_get_attribute (E_VCARD (ctx->contact), propname);
				values = attr ? e_vcard_attribute_get_values (attr) : NULL;

				for (l = values; l && !truth; l = l->next) {
					const gchar *value = l->data;

					if (value && *value)
						truth = TRUE;
				}
			}
		}
	}
	r = e_sexp_result_new (f, ESEXP_RES_BOOL);
	r->value.boolean = truth;

	return r;
}
static ESExpResult *
entry_compare (SearchContext *ctx,
               struct _ESExp *f,
               gint argc,
               struct _ESExpResult **argv,
               CompareFunc compare)
{
	ESExpResult *r;
	gint truth = FALSE;

	if ((argc == 2
		&& argv[0]->type == ESEXP_RES_STRING
		&& argv[1]->type == ESEXP_RES_STRING) ||
	    (argc == 3
		&& argv[0]->type == ESEXP_RES_STRING
		&& argv[1]->type == ESEXP_RES_STRING
		&& argv[2]->type == ESEXP_RES_STRING)) {
		gchar *propname;
		struct prop_info *info = NULL;
		const gchar *region = NULL;
		gint i;
		gboolean any_field;
		gboolean saw_any = FALSE;

		if (argc > 2)
			region = argv[2]->value.string;

		propname = argv[0]->value.string;

		any_field = !strcmp (propname, "x-evolution-any-field");
		for (i = 0; i < G_N_ELEMENTS (prop_info_table); i++) {
			if (any_field
			    || !strcmp (prop_info_table[i].query_prop, propname)) {
				saw_any = TRUE;
				info = &prop_info_table[i];

				if (any_field && info->field_id == E_CONTACT_UID) {
					/* We need to skip UID from any field contains search
					 * any-field search should be supported for the
					 * visible fields only.
					 */
					truth = FALSE;
				}
				else if (info->prop_type == PROP_TYPE_NORMAL) {
					const gchar *prop = NULL;
					/* straight string property matches */

					prop = e_contact_get_const (ctx->contact, info->field_id);

					if (prop && compare (prop, argv[1]->value.string, region)) {
						truth = TRUE;
					}
					if ((!prop) && compare ("", argv[1]->value.string, region)) {
						truth = TRUE;
					}
				}
				else if (info->prop_type == PROP_TYPE_LIST) {
					/* the special searches that match any of the list elements */
					truth = info->list_compare (ctx->contact, argv[1]->value.string, region, compare);
				}
				else if (info->prop_type == PROP_TYPE_DATE) {
					/* the special searches that match dates */
					EContactDate *date;

					date = e_contact_get (ctx->contact, info->field_id);

					if (date) {
						truth = compare_date (date, argv[1]->value.string, region, compare);
						e_contact_date_free (date);
					}
				} else {
					g_warn_if_reached ();

					saw_any = FALSE;
					break;
				}

				/* if we're looking at all fields and find a match,
				 * or if we're just looking at this one field,
				 * break. */
				if ((any_field && truth)
				    || !any_field)
					break;
			}
		}

		if (!saw_any) {
			/* propname didn't match to any of our known "special" properties,
			 * so try to find if it isn't a real field and if so, then compare
			 * against value in this field only */
			EContactField fid = e_contact_field_id (propname);

			if (fid >= E_CONTACT_FIELD_FIRST && fid < E_CONTACT_FIELD_LAST) {
				const gchar *prop = e_contact_get_const (ctx->contact, fid);

				if (prop && compare (prop, argv[1]->value.string, region)) {
					truth = TRUE;
				}

				if ((!prop) && compare ("", argv[1]->value.string, region)) {
					truth = TRUE;
				}
			} else {
				/* it is not direct EContact known field, so try to find
				 * it in EVCard attributes */
				GList *a, *attrs = e_vcard_get_attributes (E_VCARD (ctx->contact));
				for (a = attrs; a && !truth; a = a->next) {
					EVCardAttribute *attr = (EVCardAttribute *) a->data;
					if (g_ascii_strcasecmp (e_vcard_attribute_get_name (attr), propname) == 0) {
						GList *l, *values = e_vcard_attribute_get_values (attr);

						for (l = values; l && !truth; l = l->next) {
							const gchar *value = l->data;

							if (value && compare (value, argv[1]->value.string, region)) {
								truth = TRUE;
							} else if ((!value) && compare ("", argv[1]->value.string, region)) {
								truth = TRUE;
							}
						}
					}
				}
			}
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_BOOL);
	r->value.boolean = truth;

	return r;
}
Пример #11
0
/* This function returns a GtkEntry derived from field_id for a particular
 * contact.
 * Returns GtkWidget * on success, NULL on failure
 * TODO: Lots of duplicated code here, perhaps add a few bits to utils?
 */
static GtkWidget *
contacts_edit_widget_new (EContact *contact, EVCardAttribute *attr,
			  gboolean multi_line, gboolean *changed)
{
	GtkWidget *type_edit;
	EContactChangeData *data;
	const gchar *attr_name = e_vcard_attribute_get_name (attr);

	/* Create data structure for changes */
	data = g_new0 (EContactChangeData, 1);
	data->contact = contact;
	data->attr = attr;
	data->changed = changed;

	/* Create widget */
	if (!e_vcard_attribute_is_single_valued (attr)) {
		/* Handle structured fields */
		GtkWidget *adr_table;
		guint field;
		GList *values = e_vcard_attribute_get_values (attr);
		
		adr_table = gtk_table_new (1, 2, FALSE);
		gtk_table_set_col_spacings (GTK_TABLE (adr_table), 6);
		gtk_table_set_row_spacings (GTK_TABLE (adr_table), 6);
		gtk_container_set_border_width (GTK_CONTAINER (adr_table), 6);
		
		/* Set widget that contains attribute data */		
		data->widget = adr_table;
		
		/* Add type editor */
		type_edit = contacts_type_edit_widget_new (attr, multi_line,
			changed);
		if (type_edit) {
			GtkWidget *label = gtk_label_new (NULL);
			gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
			gtk_label_set_markup (GTK_LABEL (label),
                                /* TODO: make nicer for i18n */
				_("<b>Type:</b>"));
			gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
			gtk_table_attach (GTK_TABLE (adr_table), label, 0, 1,
					  0, 1, GTK_FILL, GTK_FILL, 0, 0);
			gtk_table_attach (GTK_TABLE (adr_table), type_edit,
					  1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
			gtk_widget_show (label);
			gtk_widget_show (type_edit);
		}

		/* Create sub-fields */
		for (field = 0; values; values = values->next, field++) {
			/* If no information exists, assume field is
			 * single-lined.
			 * TODO: It may be more intelligent in the future
			 * to look at the value and search for new-line
			 * characters.
			 */
			gboolean multiline = FALSE;
			GtkWidget *label = NULL, *entry;
			const ContactsStructuredField *sfield =
			    contacts_get_structured_field (attr_name, field);
			const gchar *string = (const gchar *)values->data;
			/* If we have the information, label the field */
			if (sfield) {
				gchar *label_markup;

				if (sfield->priority == 0)
					continue;

				label = gtk_label_new (NULL);
				multiline = sfield->multiline;				
				gtk_label_set_use_markup (GTK_LABEL (label),
							  TRUE);

				label_markup = g_strdup_printf (
                                        /** Translators, the first
                                         * argument is the field's
                                         * name, ex. <b>Country:</b>
                                         */				
                                        _("<b>%s:</b>"),
					gettext(sfield->subfield_name));
				gtk_label_set_markup (GTK_LABEL (label),
						      label_markup);
				g_free (label_markup);
				gtk_label_set_justify (GTK_LABEL (label),
						       GTK_JUSTIFY_RIGHT);
				if (!multiline)
					gtk_misc_set_alignment (
						GTK_MISC (label), 1, 0.5);
				else
					gtk_misc_set_alignment (
						GTK_MISC (label), 1, 0);
				gtk_table_attach (GTK_TABLE (adr_table), label,
						  0, 1, field + 1, field + 2,
						  GTK_FILL, GTK_FILL, 0, 0);
				gtk_widget_show (label);
			}
			/* This code is pretty much a verbatim copy of the
			 * code below to handle single-valued fields
			 */
			if (multiline) {
				GtkTextBuffer *buffer;
				GtkTextView *view;
				
				view = GTK_TEXT_VIEW (gtk_text_view_new ());
				gtk_widget_set_name (GTK_WIDGET (view),
						     attr_name);
				buffer = gtk_text_view_get_buffer (view);
				
				gtk_text_buffer_set_text (buffer, string ?
							   string : "", -1);
				gtk_text_view_set_editable (view, TRUE);
				gtk_text_view_set_accepts_tab (view, FALSE);
				
				entry = gtk_frame_new (NULL);
				gtk_frame_set_shadow_type (GTK_FRAME (entry),
							   GTK_SHADOW_IN);
				gtk_container_add (GTK_CONTAINER (entry),
						   GTK_WIDGET (view));
				gtk_widget_show (GTK_WIDGET (view));
				
				/* Connect signal for changes */
				g_signal_connect (G_OBJECT (buffer), "changed",
						  G_CALLBACK
						  (contacts_entry_changed),
						  data);
			} else {
				entry = gtk_entry_new ();
				gtk_widget_set_name (entry, attr_name);
				gtk_entry_set_text (GTK_ENTRY (entry),
						    string ? string : "");

				/* Connect signal for changes */
				g_signal_connect (G_OBJECT (entry), "changed",
						  G_CALLBACK
						  (contacts_entry_changed),
						  data);
			}
			gtk_widget_show (entry);
	     		/* Hide the label when the entry is hidden */
			g_signal_connect_swapped (G_OBJECT (entry), "hide", 
					  G_CALLBACK (gtk_widget_hide),
					  label);
			gtk_table_attach (GTK_TABLE (adr_table), entry,
					  1, 2, field + 1, field + 2,
					  GTK_FILL | GTK_EXPAND, GTK_FILL,
					  0, 0);
		}
	} else if (multi_line) {
		/* Handle single-valued fields that span multiple lines */
		gchar *string = e_vcard_attribute_get_value (attr);
		
		GtkWidget *container = NULL;
		GtkTextView *view = GTK_TEXT_VIEW (gtk_text_view_new ());
		GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
		
		gtk_widget_set_name (GTK_WIDGET (view), attr_name);
		gtk_text_buffer_set_text (buffer, string ? string : "", -1);
		gtk_text_view_set_editable (view, TRUE);
		gtk_text_view_set_accepts_tab (view, FALSE);
		g_free (string);

		container = gtk_frame_new (NULL);
		gtk_frame_set_shadow_type (
			GTK_FRAME (container), GTK_SHADOW_IN);
		gtk_container_add (GTK_CONTAINER (container),
				   GTK_WIDGET (view));
		gtk_widget_show (GTK_WIDGET (view));

/*		if (type_edit) {
			gtk_widget_show (type_edit);
			gtk_widget_show (window);
			container = gtk_hbox_new (FALSE, 6);
			gtk_box_pack_start (GTK_BOX (container), type_edit,
					    FALSE, TRUE, 0);
			gtk_box_pack_end (GTK_BOX (container), window,
					    TRUE, TRUE, 0);
		}*/

		/* Set widget that contains attribute data */		
		data->widget = container;
		
		/* Connect signal for changes */
		g_signal_connect (G_OBJECT (buffer), "changed", G_CALLBACK
				  (contacts_entry_changed), data);
	} else {
		/* Handle simple single-valued single-line fields */
		gchar *string = e_vcard_attribute_get_value (attr);
		GtkWidget *entry, *container = NULL;

		entry = gtk_entry_new ();
		gtk_entry_set_text (GTK_ENTRY (entry),
				    string ? string : "");
		gtk_widget_set_name (entry, attr_name);
		g_free (string);

/*		if (type_edit) {
			gtk_widget_show (type_edit);
			gtk_widget_show (entry);
			container = gtk_hbox_new (FALSE, 6);
			gtk_box_pack_start (GTK_BOX (container), type_edit,
					    FALSE, TRUE, 0);
			gtk_box_pack_end (GTK_BOX (container), entry,
					    TRUE, TRUE, 0);
		}*/

		/* Set widget that contains attribute data */		
		data->widget = container ? container : entry;
		
		/* Connect signal for changes */
		g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK
				  (contacts_entry_changed), data);
	}

	/* Free change data structure on destruction */
	g_signal_connect_swapped (G_OBJECT (data->widget), "destroy", 
				  G_CALLBACK (g_free), data);
	
	gtk_widget_set_name (data->widget, attr_name);
	return data->widget;
}
Пример #12
0
/* utility functions shared between all contact importers */
static void
preview_contact (EWebViewPreview *preview,
                 EContact *contact)
{
	gint idx;
	gboolean had_value = FALSE;

	const gint fields[] = {
		E_CONTACT_FILE_AS,
		E_CONTACT_CATEGORIES,

		E_CONTACT_IS_LIST,
		E_CONTACT_LIST_SHOW_ADDRESSES,
		E_CONTACT_WANTS_HTML,

		E_CONTACT_FULL_NAME,
		E_CONTACT_GIVEN_NAME,
		E_CONTACT_FAMILY_NAME,
		E_CONTACT_NICKNAME,
		E_CONTACT_SPOUSE,
		E_CONTACT_BIRTH_DATE,
		E_CONTACT_ANNIVERSARY,
		E_CONTACT_MAILER,
		E_CONTACT_EMAIL,

		-1,

		E_CONTACT_ORG,
		E_CONTACT_ORG_UNIT,
		E_CONTACT_OFFICE,
		E_CONTACT_TITLE,
		E_CONTACT_ROLE,
		E_CONTACT_MANAGER,
		E_CONTACT_ASSISTANT,

		-1,

		E_CONTACT_PHONE_ASSISTANT,
		E_CONTACT_PHONE_BUSINESS,
		E_CONTACT_PHONE_BUSINESS_2,
		E_CONTACT_PHONE_BUSINESS_FAX,
		E_CONTACT_PHONE_CALLBACK,
		E_CONTACT_PHONE_CAR,
		E_CONTACT_PHONE_COMPANY,
		E_CONTACT_PHONE_HOME,
		E_CONTACT_PHONE_HOME_2,
		E_CONTACT_PHONE_HOME_FAX,
		E_CONTACT_PHONE_ISDN,
		E_CONTACT_PHONE_MOBILE,
		E_CONTACT_PHONE_OTHER,
		E_CONTACT_PHONE_OTHER_FAX,
		E_CONTACT_PHONE_PAGER,
		E_CONTACT_PHONE_PRIMARY,
		E_CONTACT_PHONE_RADIO,
		E_CONTACT_PHONE_TELEX,
		E_CONTACT_PHONE_TTYTDD,

		-1,

		E_CONTACT_ADDRESS_HOME,
		E_CONTACT_ADDRESS_WORK,
		E_CONTACT_ADDRESS_OTHER,

		-1,

		E_CONTACT_HOMEPAGE_URL,
		E_CONTACT_BLOG_URL,
		E_CONTACT_CALENDAR_URI,
		E_CONTACT_FREEBUSY_URL,
		E_CONTACT_ICS_CALENDAR,
		E_CONTACT_VIDEO_URL,

		-1,

		E_CONTACT_IM_AIM,
		E_CONTACT_IM_GROUPWISE,
		E_CONTACT_IM_JABBER,
		E_CONTACT_IM_YAHOO,
		E_CONTACT_IM_MSN,
		E_CONTACT_IM_ICQ,
		E_CONTACT_IM_GADUGADU,
		E_CONTACT_IM_SKYPE,

		-1,

		E_CONTACT_NOTE
	};

	g_return_if_fail (preview != NULL);
	g_return_if_fail (contact != NULL);

	for (idx = 0; idx < G_N_ELEMENTS (fields); idx++) {
		EContactField field;

		if (fields[idx] == -1) {
			if (had_value)
				e_web_view_preview_add_empty_line (preview);
			had_value = FALSE;
			continue;
		}

		field = fields[idx];

		if (field == E_CONTACT_BIRTH_DATE || field == E_CONTACT_ANNIVERSARY) {
			EContactDate *dt = e_contact_get (contact, field);
			if (dt) {
				GDate gd = { 0 };
				struct tm tm;
				gchar *value;

				g_date_set_dmy (&gd, dt->day, dt->month, dt->year);
				g_date_to_struct_tm (&gd, &tm);

				value = e_datetime_format_format_tm (
					"addressbook", "table",
					DTFormatKindDate, &tm);
				if (value) {
					e_web_view_preview_add_section (
						preview,
						e_contact_pretty_name (field),
						value);
					had_value = TRUE;
				}

				g_free (value);
				e_contact_date_free (dt);
			}
		} else if (field == E_CONTACT_IS_LIST ||
			   field == E_CONTACT_WANTS_HTML ||
			   field == E_CONTACT_LIST_SHOW_ADDRESSES) {
			if (e_contact_get (contact, field)) {
				e_web_view_preview_add_text (
					preview, e_contact_pretty_name (field));
				had_value = TRUE;
			}
		} else if (field == E_CONTACT_ADDRESS_HOME ||
			   field == E_CONTACT_ADDRESS_WORK ||
			   field == E_CONTACT_ADDRESS_OTHER) {
			EContactAddress *addr = e_contact_get (contact, field);
			if (addr) {
				gboolean have = FALSE;

				#define add_it(_what)	\
					if (addr->_what && *addr->_what) {	\
						e_web_view_preview_add_section ( \
							preview, have ? NULL : \
							e_contact_pretty_name (field), addr->_what);	\
						have = TRUE;	\
						had_value = TRUE;	\
					}

				add_it (po);
				add_it (ext);
				add_it (street);
				add_it (locality);
				add_it (region);
				add_it (code);
				add_it (country);

				#undef add_it

				e_contact_address_free (addr);
			}
		} else if (field == E_CONTACT_IM_AIM ||
			   field == E_CONTACT_IM_GROUPWISE ||
			   field == E_CONTACT_IM_JABBER ||
			   field == E_CONTACT_IM_YAHOO ||
			   field == E_CONTACT_IM_MSN ||
			   field == E_CONTACT_IM_ICQ ||
			   field == E_CONTACT_IM_GADUGADU ||
			   field == E_CONTACT_IM_SKYPE ||
			   field == E_CONTACT_EMAIL) {
			GList *attrs, *a;
			gboolean have = FALSE;
			const gchar *pretty_name;

			pretty_name = e_contact_pretty_name (field);

			attrs = e_contact_get_attributes (contact, field);
			for (a = attrs; a; a = a->next) {
				EVCardAttribute *attr = a->data;
				GList *value;

				if (!attr)
					continue;

				value = e_vcard_attribute_get_values (attr);

				while (value != NULL) {
					const gchar *str = value->data;

					if (str && *str) {
						e_web_view_preview_add_section (
							preview, have ? NULL :
							pretty_name, str);
						have = TRUE;
						had_value = TRUE;
					}

					value = value->next;
				}

				e_vcard_attribute_free (attr);
			}

			g_list_free (attrs);

		} else if (field == E_CONTACT_CATEGORIES) {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}

		} else {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}
		}
	}
}
Пример #13
0
static void
vcard_import_contact (VCardImporter *gci,
                      EContact *contact)
{
	EContactPhoto *photo;
	GList *attrs, *attr;
	gchar *uid = NULL;

	/* Apple's addressbook.app exports PHOTO's without a TYPE
	 * param, so let's figure out the format here if there's a
	 * PHOTO attribute missing a TYPE param.
	 *
	 * this is sort of a hack, as EContact sets the type for us if
	 * we use the setter.  so let's e_contact_get + e_contact_set
	 * on E_CONTACT_PHOTO.
	*/
	photo = e_contact_get (contact, E_CONTACT_PHOTO);
	if (photo) {
		e_contact_set (contact, E_CONTACT_PHOTO, photo);
		e_contact_photo_free (photo);
	}

	/* Deal with our XML EDestination stuff in EMAIL attributes, if there is any. */
	attrs = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		GList *v = e_vcard_attribute_get_values (a);

		if (v && v->data) {
			if (!strncmp ((gchar *)v->data, "<?xml", 5)) {
				EDestination *dest = e_destination_import ((gchar *) v->data);

				e_destination_export_to_vcard_attribute (dest, a);

				g_object_unref (dest);

			}
		}
	}
	e_contact_set_attributes (contact, E_CONTACT_EMAIL, attrs);

	/* Deal with TEL attributes that don't conform to what we need.
	 *
	 * 1. if there's no location (HOME/WORK/OTHER), default to OTHER.
	 * 2. if there's *only* a location specified, default to VOICE.
	 */
	attrs = e_vcard_get_attributes (E_VCARD (contact));
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		gboolean location_only = TRUE;
		gboolean no_location = TRUE;
		gboolean is_work_home = FALSE;
		GList *params, *param;

		if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a),
					EVC_TEL))
			continue;

		params = e_vcard_attribute_get_params (a);
		for (param = params; param; param = param->next) {
			EVCardAttributeParam *p = param->data;
			GList *vs, *v;

			if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
						EVC_TYPE))
				continue;

			vs = e_vcard_attribute_param_get_values (p);
			for (v = vs; v; v = v->next) {
				is_work_home = is_work_home ||
					!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
					!g_ascii_strcasecmp ((gchar *)v->data, "HOME");

				if (!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "HOME") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "OTHER"))
					no_location = FALSE;
				else
					location_only = FALSE;
			}
		}

		if (is_work_home) {
			/* only WORK and HOME phone numbers require locations,
			 * the rest should be kept as is */
			if (location_only) {
				/* add VOICE */
				e_vcard_attribute_add_param_with_value (a,
									e_vcard_attribute_param_new (EVC_TYPE),
									"VOICE");
			}
			if (no_location) {
				/* add OTHER */
				e_vcard_attribute_add_param_with_value (a,
									e_vcard_attribute_param_new (EVC_TYPE),
									"OTHER");
			}
		}
	}

	/* Deal with ADR and EMAIL attributes that don't conform to what
	 * we need.  If HOME or WORK isn't specified, add TYPE=OTHER. */
	attrs = e_vcard_get_attributes (E_VCARD (contact));
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		gboolean no_location = TRUE;
		GList *params, *param;

		if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_ADR) &&
		    g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_EMAIL))
			continue;

		params = e_vcard_attribute_get_params (a);
		for (param = params; param; param = param->next) {
			EVCardAttributeParam *p = param->data;
			GList *vs, *v;

			if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
						EVC_TYPE))
				continue;

			vs = e_vcard_attribute_param_get_values (p);
			for (v = vs; v; v = v->next) {
				if (!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "HOME"))
					no_location = FALSE;
			}
		}

		if (no_location) {
			/* add OTHER */
			e_vcard_attribute_add_param_with_value (a,
								e_vcard_attribute_param_new (EVC_TYPE),
								"OTHER");
		}
	}

	/* Work around the fact that these fields no longer show up in the UI */
	add_to_notes (contact, E_CONTACT_OFFICE);
	add_to_notes (contact, E_CONTACT_SPOUSE);
	add_to_notes (contact, E_CONTACT_BLOG_URL);

	/* FIXME Error checking */
	if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
		e_contact_set (contact, E_CONTACT_UID, uid);
		g_free (uid);
	}
}