/* * 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; }
static char *evcard_to_string(EVCard *evcard, unsigned int format, uint64_t filter) { EVCard *evcard2; GList *l; char *vcard; if (!filter) return e_vcard_to_string(evcard, EVC_FORMAT_VCARD_30); /* XXX There is no support for VCARD 2.1 at this time */ /* * Mandatory attributes for vCard 2.1 are VERSION ,N and TEL. * Mandatory attributes for vCard 3.0 are VERSION, N, FN and TEL */ filter = format == EVC_FORMAT_VCARD_30 ? filter | 0x87: filter | 0x85; l = e_vcard_get_attributes(evcard); evcard2 = e_vcard_new(); for (; l; l = g_list_next(l)) { EVCardAttribute *attrib = l->data; const char *name; int i; if (!attrib) continue; name = e_vcard_attribute_get_name(attrib); for (i = 0; attribute_mask[i] != NULL; i++) { if (!(filter & (1 << i))) continue; if (g_strcmp0(name, attribute_mask[i]) != 0) continue; e_vcard_add_attribute(evcard2, e_vcard_attribute_copy(attrib)); } } vcard = e_vcard_to_string(evcard2, format); g_object_unref(evcard2); return vcard; }
static gboolean has_only_one (EVCard *vcard, const gchar *attrname) { gboolean found = FALSE; GList *iter; for (iter = e_vcard_get_attributes (vcard); iter; iter = iter->next) { EVCardAttribute *attr = iter->data; if (g_strcmp0 (e_vcard_attribute_get_name (attr), attrname) == 0) { if (found) return FALSE; found = TRUE; } } return found; }
/** * e_vcard_get_attribute: * @evc: an #EVCard * @name: the name of the attribute to get * * Get the attribute @name from @evc. The #EVCardAttribute is owned by * @evcard and should not be freed. If the attribute does not exist, #NULL is * returned. * * Return value: An #EVCardAttribute if found, or #NULL. **/ EVCardAttribute * e_vcard_get_attribute (EVCard *evc, const char *name) { GList *attrs, *l; g_return_val_if_fail (E_IS_VCARD (evc), NULL); g_return_val_if_fail (name != NULL, NULL); attrs = e_vcard_get_attributes (evc); for (l = attrs; l; l = l->next) { EVCardAttribute *attr; attr = (EVCardAttribute *) l->data; if (g_ascii_strcasecmp (attr->name, name) == 0) return attr; } return NULL; }
/* Get a list of the specified attributes from a contact */ GList * hito_vcard_get_named_attributes (EVCard *contact, const char *name) { GList *attrs = NULL, *l; g_return_val_if_fail (E_IS_VCARD (contact), NULL); g_return_val_if_fail (name != NULL, NULL); for (l = e_vcard_get_attributes (E_VCARD (contact)); l; l = l->next) { EVCardAttribute *attr; const char *n; attr = (EVCardAttribute *) l->data; n = e_vcard_attribute_get_name (attr); if (strcmp (n, name) == 0) attrs = g_list_prepend (attrs, attr); } return g_list_reverse (attrs); }
/* 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 * 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; }
void contacts_edit_pane_show (ContactsData *data, gboolean new) { GtkWidget *align, *button, *widget/*, *glabel, *gbutton*/; GdkPixbuf *pixbuf; GtkWidget *image; EVCardAttribute *groups_attr = NULL; ContactsGroupChangeData *gdata; guint row, i; GList *attributes, *c, *d, *label_widgets, *edit_widgets; EContact *contact = data->contact; const ContactsField *contacts_fields = contacts_get_contacts_fields (); #ifdef DEBUG /* Prints out all contact data */ attributes = e_vcard_get_attributes (E_VCARD (contact)); for (c = attributes; c; c = c->next) { EVCardAttribute *a = (EVCardAttribute*)c->data; GList *params = e_vcard_attribute_get_params (a); GList *values = e_vcard_attribute_get_values (a); g_printf ("%s:\n", e_vcard_attribute_get_name (a)); for (; values; values = values->next) { g_printf (" %s\n", (const gchar *)values->data); } if (params) g_print ("Attributes: \n"); for (; params; params = params->next) { EVCardAttributeParam *p = (EVCardAttributeParam *)params->data; GList *paramvalues = e_vcard_attribute_param_get_values (p);
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); } }