g_warning (G_STRLOC ": db->get failed with %d", db_error);
return GNOME_Evolution_Addressbook_ContactNotFound;
}
- free (vcard_dbt.data);
+ g_free (vcard_dbt.data);
/* update the revisio (modified time of contact) */
set_revision (*contact);
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0) {
- *vcard = g_strdup (vcard_dbt.data);
- free (vcard_dbt.data);
+ *vcard = vcard_dbt.data;
return GNOME_Evolution_Addressbook_Success;
} else {
g_warning (G_STRLOC ": db->get failed with %d", db_error);
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0) {
- contact_list = g_list_append (contact_list, g_strdup (vcard_dbt.data));
+ contact_list = g_list_append (contact_list, vcard_dbt.data);
} else {
g_warning (G_STRLOC ": db->get failed with %d", db_error);
status = GNOME_Evolution_Addressbook_OtherError ;
}
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+ vcard_dbt.flags = DB_DBT_MALLOC;
memset (&id_dbt, 0, sizeof (id_dbt));
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
|| strcmp (id_dbt.data, E_BOOK_BACKEND_FILE_VERSION_NAME)) {
if ((!search_needed) || (card_sexp != NULL && e_book_backend_sexp_match_vcard (card_sexp, vcard_dbt.data))) {
- contact_list = g_list_append (contact_list, g_strdup (vcard_dbt.data));
+ contact_list = g_list_append (contact_list, vcard_dbt.data);
}
}
DB *db;
DBT id_dbt, vcard_dbt;
int db_error;
- gboolean stopped = FALSE;
+ gboolean stopped = FALSE, allcontacts;
d(printf ("starting initial population of book view\n"));
db = bf->priv->file_db;
query = e_data_book_view_get_card_query (book_view);
- if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) {
e_data_book_view_notify_status_message (book_view, _("Loading..."));
- else
+ allcontacts = TRUE;
+ } else {
e_data_book_view_notify_status_message (book_view, _("Searching..."));
+ allcontacts = FALSE;
+ }
d(printf ("signalling parent thread\n"));
g_mutex_lock (closure->mutex);
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0) {
- /* notify_update will check if it matches for us */
- e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
+ e_data_book_view_notify_update_prefiltered_vcard (book_view, id, vcard_dbt.data);
}
else {
g_warning (G_STRLOC ": db->get failed with %d", db_error);
/* don't include the version in the list of cards */
if (strcmp (id_dbt.data, E_BOOK_BACKEND_FILE_VERSION_NAME)) {
- /* notify_update will check if it matches for us */
- e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
+ if (allcontacts)
+ e_data_book_view_notify_update_prefiltered_vcard (book_view, id_dbt.data, vcard_dbt.data);
+ else
+ e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
+ } else {
+ g_free (vcard_dbt.data);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
g_object_unref (contact);
- free (vcard_dbt.data);
+ g_free (vcard_dbt.data);
}
}
db_error = db->get (db, NULL, &version_name_dbt, &version_dbt, 0);
if (db_error == 0) {
/* success */
- version = g_strdup (version_dbt.data);
- free (version_dbt.data);
+ version = version_dbt.data;
}
else {
/* key was not in file */
return GNOME_Evolution_Addressbook_OtherError;
}
+ /* Set the allocation routines to the non-aborting GLib functions */
+ env->set_alloc (env, (void *(*)(size_t))g_try_malloc,
+ (void *(*)(void *, size_t))g_try_realloc,
+ g_free);
+
db_error = env->open (env, NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
if (db_error != 0) {
env->close(env, 0);
}
/**
+ * e_data_book_view_notify_update_prefiltered_vcard:
+ * @book_view: an #EDataBookView
+ * @id: the UID of this contact
+ * @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.
+ *
+ * The important difference between this method and
+ * #e_data_book_view_notify_update and #e_data_book_view_notify_update_vcard is
+ * that it doesn't match the contact against the book view query to see if it
+ * should be included, it assumes that this has been done and the contact is
+ * known to exist in the view.
+ **/
+void
+e_data_book_view_notify_update_prefiltered_vcard (EDataBookView *book_view, const char *id, char *vcard)
+{
+ gboolean currently_in_view;
+
+ g_mutex_lock (book_view->priv->pending_mutex);
+
+ currently_in_view =
+ g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+
+ if (currently_in_view)
+ notify_change (book_view, vcard);
+ else
+ notify_add (book_view, id, vcard);
+
+ g_mutex_unlock (book_view->priv->pending_mutex);
+}
+
+/**
* e_data_book_view_notify_remove:
* @book_view: an #EDataBookView
* @id: a unique contact ID