static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts, void *user_data) { struct query_context *data = user_data; GList *l; if (estatus == E_BOOK_ERROR_CANCELLED) { error("E-Book operation was cancelled: status %d", estatus); goto fail; } data->completed = TRUE; if (estatus != E_BOOK_ERROR_OK) { error("E-Book query failed: status %d", estatus); goto done; } for (l = contacts; l; l = g_list_next(l)) { EContact *contact = E_CONTACT(l->data); EVCard *evcard = E_VCARD(contact); EVCardAttribute *attrib; char *uid, *tel, *name; name = evcard_name_attribute_to_string(evcard); if (!name) continue; attrib = e_vcard_get_attribute(evcard, EVC_UID); if (!attrib) continue; uid = e_vcard_attribute_get_value(attrib); if (!uid) continue; attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (!attrib) continue; tel = e_vcard_attribute_get_value(attrib); data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL, tel, data->user_data); g_free(name); g_free(uid); g_free(tel); } done: data->ready_cb(data->user_data); fail: if (data->completed) g_free(data); }
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; }
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); }
static void verify_premodify_and_prepare_contact (EContact *contact) { EVCardAttribute *attr; /* ensure there is no email address to begin with, then add one */ g_assert (!e_vcard_get_attribute (E_VCARD (contact), EVC_EMAIL)); attr = e_vcard_attribute_new (NULL, EVC_EMAIL); e_vcard_add_attribute_with_value (E_VCARD (contact), attr, EMAIL_ADD); }
static void verify_commit (EContact *contact) { EVCardAttribute *attr; gchar *email_value; g_assert ((attr = e_vcard_get_attribute (E_VCARD (contact), EVC_EMAIL))); g_assert (e_vcard_attribute_is_single_valued (attr)); email_value = e_vcard_attribute_get_value (attr); g_assert (!g_strcmp0 (email_value, EMAIL_ADD)); }
static gboolean compare_single_value (EVCard *vcard, const gchar *attrname, const gchar *expected_value) { EVCardAttribute *attr; gchar *str; g_return_val_if_fail (vcard != NULL, FALSE); g_return_val_if_fail (attrname != NULL, FALSE); g_return_val_if_fail (expected_value != NULL, FALSE); attr = e_vcard_get_attribute (vcard, attrname); g_return_val_if_fail (attr != NULL, FALSE); str = e_vcard_attribute_get_value (attr); g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (g_strcmp0 (str, expected_value) == 0, FALSE); g_free (str); return TRUE; }
static gboolean test_vcard (const gchar *vcard_str) { EVCard *vc1, *vc2; gchar *str; /* Do not parse */ vc1 = e_vcard_new_from_string (vcard_str); str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30); g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE); g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE); g_free (str); /* parse */ e_vcard_get_attribute (vc1, "UID"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE); str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30); g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE); g_free (str); /* parse */ e_vcard_get_attribute (vc1, "FN"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE); str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30); g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE); g_free (str); g_object_unref (vc1); /* do not parse */ vc1 = e_vcard_new_from_string (vcard_str); /* Setting the UID does not cause vCard parsing */ e_vcard_append_attribute_with_value (vc1, e_vcard_attribute_new (NULL, "UID"), "other-uid"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE); /* Retrieving the UID should not cause vCard parsing either */ g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE); g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE); /* Getting FN attribute WILL cause parsing */ e_vcard_get_attribute (vc1, "FN"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE); g_object_unref (vc1); /* parse */ vc1 = e_vcard_new_from_string (vcard_str); g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE); e_vcard_remove_attributes (vc1, NULL, "UID"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE); e_vcard_append_attribute_with_value (vc1, e_vcard_attribute_new (NULL, "UID"), "other-uid"); g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE); str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30); vc2 = e_vcard_new_from_string (str); g_free (str); g_return_val_if_fail (compare_single_value (vc2, "UID", "other-uid"), FALSE); g_object_unref (vc2); /* parse */ e_vcard_get_attribute (vc1, "FN"); g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE); g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE); str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30); vc2 = e_vcard_new_from_string (str); g_return_val_if_fail (e_vcard_is_parsed (vc2) == FALSE, FALSE); g_free (str); g_return_val_if_fail (compare_single_value (vc2, "UID", "other-uid"), FALSE); g_return_val_if_fail (has_only_one (vc1, "UID"), FALSE); g_return_val_if_fail (has_only_one (vc2, "UID"), FALSE); g_object_unref (vc2); g_object_unref (vc1); return TRUE; }
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; }
void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb, phonebook_cache_ready_cb ready_cb, void *user_data, int *err) { struct query_context *data; EBookQuery *query; GSList *l; EContact *me; EVCard *evcard; GError *gerr = NULL; EBook *eb; EVCardAttribute *attrib; char *uid, *tel, *cname; if (g_strcmp0(PB_CONTACTS_FOLDER, name) != 0) { if (err) *err = -ENOENT; return NULL; } DBG(""); query = e_book_query_any_field_contains(""); data = g_new0(struct query_context, 1); data->entry_cb = entry_cb; data->ready_cb = ready_cb; data->user_data = user_data; data->query = query; data->ebooks = open_ebooks(); /* Add 0.vcf */ if (e_book_get_self(&me, &eb, &gerr) == FALSE) { g_error_free(gerr); goto next; } evcard = E_VCARD(me); cname = evcard_name_attribute_to_string(evcard); if (!cname) cname = g_strdup(""); attrib = e_vcard_get_attribute(evcard, EVC_UID); uid = e_vcard_attribute_get_value(attrib); if (!uid) uid = g_strdup(""); attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (attrib) tel = e_vcard_attribute_get_value(attrib); else tel = g_strdup(""); data->entry_cb(uid, 0, cname, NULL, tel, data->user_data); data->count++; g_free(cname); g_free(uid); g_free(tel); g_object_unref(eb); next: for (l = data->ebooks; l != NULL; l = g_slist_next(l)) { EBook *ebook = l->data; if (e_book_is_opened(ebook) == FALSE) continue; if (e_book_get_contacts_async(ebook, query, cache_cb, data) == TRUE) data->queued_calls++; } if (err) *err = (data->queued_calls == 0 ? -ENOENT : 0); return data; }
static void cache_cb(EBook *book, const GError *gerr, GList *contacts, void *user_data) { struct query_context *data = user_data; GList *l; data->queued_calls--; if (data->canceled) goto canceled; if (gerr != NULL) { error("E-Book operation failed: %s", gerr->message); goto done; } DBG(""); for (l = contacts; l; l = g_list_next(l)) { EContact *contact = E_CONTACT(l->data); EVCard *evcard = E_VCARD(contact); EVCardAttribute *attrib; char *uid, *tel, *name; name = evcard_name_attribute_to_string(evcard); if (!name) continue; attrib = e_vcard_get_attribute(evcard, EVC_UID); if (!attrib) continue; uid = e_vcard_attribute_get_value(attrib); if (!uid) continue; attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (attrib) tel = e_vcard_attribute_get_value(attrib); else tel = g_strdup(""); data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL, tel, data->user_data); g_free(name); g_free(uid); g_free(tel); } g_list_free_full(contacts, g_object_unref); done: if (data->queued_calls == 0) data->ready_cb(data->user_data); return; canceled: if (data->queued_calls == 0) free_query_context(data); }
static void contacts_entry_changed (GtkWidget *widget, EContactChangeData *data) { GList *v, *values = contacts_entries_get_values (data->widget, NULL); e_vcard_attribute_remove_values (data->attr); /* Note: First element of a structured field is type, so remove it */ if (g_list_length (values) > 1) { GList *type = g_list_last (values); values = g_list_remove_link (values, type); g_free (type->data); g_list_free (type); } for (v = g_list_last (values); v; v = v->prev) { e_vcard_attribute_add_value (data->attr, (const gchar *)v->data); } if (!g_ascii_strcasecmp (e_vcard_attribute_get_name (data->attr), EVC_FN)) { /* add N and X-EVOLUTION-FILE-AS attributes */ ENameWestern *name; gchar *file_as; EVCardAttribute *attr; EVCard *evc = E_VCARD (data->contact); name = e_name_western_parse ((char*)values->data); /* Add "N" attribute */ attr = e_vcard_get_attribute (evc, EVC_N); if (attr) e_vcard_attribute_remove_values (attr); else { attr = e_vcard_attribute_new ("", EVC_N); e_vcard_add_attribute (evc, attr); } #define SAFESTR(x) (x) ? x : "" e_vcard_attribute_add_value (attr, SAFESTR (name->last)); e_vcard_attribute_add_value (attr, SAFESTR (name->first)); e_vcard_attribute_add_value (attr, SAFESTR (name->middle)); e_vcard_attribute_add_value (attr, SAFESTR (name->prefix)); e_vcard_attribute_add_value (attr, SAFESTR (name->suffix)); /* Add file-as attribute for evolution */ file_as = g_strdup_printf ("%s, %s", name->last, name->first); attr = e_vcard_get_attribute (evc, EVC_X_FILE_AS); if (attr) e_vcard_remove_attribute (evc, attr); attr = e_vcard_attribute_new ("", EVC_X_FILE_AS); e_vcard_add_attribute_with_value (evc, attr, file_as); g_free (file_as); g_free (name); } g_list_foreach (values, (GFunc)g_free, NULL); g_list_free (values); *data->changed = TRUE; }