static void scan_objects (gpointer data, gpointer user_data) { ScanContext *context; ScalixContact *contact; EBookBackendSExp *sexp; char *ostr; gboolean is_search; context = (ScanContext *) user_data; contact = SCALIX_CONTACT (data); sexp = context->sexp; is_search = context->search_needed; if (!is_search || e_book_backend_sexp_match_contact (sexp, E_CONTACT (contact))) { if (context->return_objects == TRUE) { context->obj_list = g_list_prepend (context->obj_list, g_object_ref (contact)); } else { ostr = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); context->obj_list = g_list_prepend (context->obj_list, ostr); } } }
/** * e_book_backend_db_cache_get_contacts: * @db: DB Handle * @query: an s-expression * * Returns a list of #EContact elements from @cache matching @query. * When done with the list, the caller must unref the contacts and * free the list. * * Returns: A #GList of pointers to #EContact. **/ GList * e_book_backend_db_cache_get_contacts (DB *db, const gchar *query) { DBC *dbc; DBT uid_dbt, vcard_dbt; gint db_error; GList *list = NULL; EBookBackendSExp *sexp = NULL; EContact *contact; if (query) { sexp = e_book_backend_sexp_new (query); if (!sexp) return NULL; } db_error = db->cursor (db, NULL, &dbc, 0); if (db_error != 0) { g_warning ("db->cursor failed with %d", db_error); if (sexp) g_object_unref (sexp); return NULL; } memset (&vcard_dbt, 0 , sizeof (vcard_dbt)); memset (&uid_dbt, 0, sizeof (uid_dbt)); db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_FIRST); while (db_error == 0) { if (vcard_dbt.data && !strncmp (vcard_dbt.data, "BEGIN:VCARD", 11)) { contact = e_contact_new_from_vcard (vcard_dbt.data); if (!sexp || e_book_backend_sexp_match_contact (sexp, contact)) list = g_list_prepend (list, contact); else g_object_unref (contact); } db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_NEXT); } db_error = dbc->c_close (dbc); if (db_error != 0) g_warning ("db->c_close failed with %d", db_error); if (sexp) g_object_unref (sexp); return g_list_reverse (list); }
/** * e_book_backend_sexp_match_vcard: * @sexp: an #EBookBackendSExp * @vcard: a VCard string * * Checks if @vcard matches @sexp. * * Returns: %TRUE if the VCard matches, %FALSE otherwise. **/ gboolean e_book_backend_sexp_match_vcard (EBookBackendSExp *sexp, const gchar *vcard) { EContact *contact; gboolean retval; contact = e_contact_new_from_vcard (vcard); retval = e_book_backend_sexp_match_contact (sexp, contact); g_object_unref (contact); return retval; }
/** * e_data_book_view_notify_update: * @book_view: an #EDataBookView * @contact: an #EContact * * Notify listeners that @contact has changed. This can * trigger an add, change or removal event depending on * whether the change causes the contact to start matching, * no longer match, or stay matching the query specified * by @book_view. **/ void e_data_book_view_notify_update (EDataBookView *book_view, EContact *contact) { EDataBookViewPrivate *priv = book_view->priv; gboolean currently_in_view, want_in_view; const gchar *id; gchar *vcard; if (!priv->running) return; g_mutex_lock (priv->pending_mutex); id = e_contact_get_const (contact, E_CONTACT_UID); currently_in_view = id_is_in_view (book_view, id); want_in_view = e_book_backend_sexp_match_contact (priv->card_sexp, contact); if (want_in_view) { vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); if (currently_in_view) notify_change (book_view, vcard); else notify_add (book_view, id, vcard); g_free (vcard); } else { if (currently_in_view) notify_remove (book_view, id); /* else nothing; we're removing a card that wasn't there */ } g_mutex_unlock (priv->pending_mutex); }
/** * e_data_book_view_notify_update_vcard: * @book_view: an #EDataBookView * @vcard: a plain vCard * * Notify listeners that @vcard has changed. This can * trigger an add, change or removal event depending on * whether the change causes the contact to start matching, * no longer match, or stay matching the query specified * by @book_view. This method should be preferred over * #e_data_book_view_notify_update when the native * representation of a contact is a vCard. **/ void e_data_book_view_notify_update_vcard (EDataBookView *book_view, gchar *vcard) { EDataBookViewPrivate *priv = book_view->priv; gboolean currently_in_view, want_in_view; const gchar *id; EContact *contact; if (!priv->running) { g_free (vcard); return; } g_mutex_lock (priv->pending_mutex); contact = e_contact_new_from_vcard (vcard); id = e_contact_get_const (contact, E_CONTACT_UID); currently_in_view = id_is_in_view (book_view, id); want_in_view = e_book_backend_sexp_match_contact (priv->card_sexp, contact); if (want_in_view) { if (currently_in_view) notify_change (book_view, vcard); else notify_add (book_view, id, vcard); } else { if (currently_in_view) notify_remove (book_view, id); } /* Do this last so that id is still valid when notify_ is called */ g_object_unref (contact); g_free (vcard); g_mutex_unlock (priv->pending_mutex); }