aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Toshok <toshok@ximian.com>2003-02-08 17:06:46 +0800
committerChris Toshok <toshok@src.gnome.org>2003-02-08 17:06:46 +0800
commit0db95c91b293f6b1c87be3c0abdd1fb2b0ac5b42 (patch)
treedd2ae6faaeed6aa9002427a87cc573e4e8e4ef05
parentaaa6c778e8c8458e107f564d12f1089880810f04 (diff)
downloadgsoc2013-evolution-0db95c91b293f6b1c87be3c0abdd1fb2b0ac5b42.tar.gz
gsoc2013-evolution-0db95c91b293f6b1c87be3c0abdd1fb2b0ac5b42.tar.zst
gsoc2013-evolution-0db95c91b293f6b1c87be3c0abdd1fb2b0ac5b42.zip
[ huge change, all for 1 little performance problem :) fixes #18207 ] use
2003-02-08 Chris Toshok <toshok@ximian.com> [ huge change, all for 1 little performance problem :) fixes #18207 ] * gui/widgets/e-addressbook-model.c (get_view): use e_book_check_static_capability here to make things a little prettier. (remove_card): complain about my life, and add code to use one "model_changed" signal if we get back a list of cards instead of multiple "card_removed" signals. * gui/widgets/e-addressbook-model.h: little clean up. * gui/widgets/e-addressbook-view.c (delete): write a bulk-remove case for this. if the backend supports it, send all the ids at once. otherwise loop over the ids. (e_addressbook_view_delete_selection): fake a CardAndBook structure and call delete, instead of duplicating the code in 2 places. * gui/component/addressbook.c (delete_contact_cb): don't call e_contact_editor_confirm_delete here, it's handled by the EAddressbookView. * backend/pas/pas-card-cursor.c (pas_card_cursor_construct): fix a compiler warning about a stupid crash. * backend/pas/pas-book.h (PASOperation): RemoveCard -> RemoveCards. (PASRemoveCardsReques): char *id -> GList *ids. (PASRequest): PASRemoveCardRequest -> PASRemoveCardsRequest. * backend/pas/pas-book.c (pas_book_queue_remove_cards): build up a GList from the id sequence. (pas_book_respond_remove): notifyCardRemoved -> notifyCardsRemoved. (impl_GNOME_Evolution_Addressbook_Book_removeCards): rename. (pas_book_free_request): free the idlist for RemoveCards. (pas_book_class_init): removeCard -> removeCards. * backend/pas/pas-book-view.h: change prototype for pas_book_view_notify_remove, and add prototype for pas_book_view_notify_remove_1. * backend/pas/pas-book-view.c (pas_book_view_notify_remove_1): build up a list and call pas_book_view_notify_remove. (pas_book_view_notify_remove): build up the corba id sequence and call BookViewListener::notifyCardsRemoved. * backend/pas/pas-backend.h: remove_card -> remove_cards. * backend/pas/pas-backend.c (pas_backend_remove_cards): rename from _remove_card. (process_client_requests): RemoveCard -> RemoveCards and _remove_card -> _remove_cards. * backend/pas/pas-backend-ldap.c (check_schema_support): g_strcasecmp -> g_ascii_strcasecmp. (remove_card_handler): _remove => _remove_1. (modify_card_modify_handler): same. (pas_backend_ldap_process_remove_cards): rename from _remove_card. (pas_backend_ldap_class_init): _remove_card -> _remove_cards. * backend/pas/pas-backend-file.c (pas_backend_file_class_init): remove_card -> remove_cards. (pas_backend_file_get_static_capabilities): add "bulk-removes". (pas_backend_file_process_remove_cards): rewrite this function largely, so that it handles lists of ids. first we loop through and for every successful deletion we build a list of deleted ECards. Then for each view we build a list (a subset of the deleted ECard list) and pass back that list to the view. (pas_backend_file_process_modify_card): use _remove_1 instead of _remove. (ecard_matches_search): new function. * backend/pas/pas-backend-card-sexp.c (pas_backend_card_sexp_match_vcard): rewrite in terms of _match_ecard. (pas_backend_card_sexp_match_ecard): new function, the guts from _match_vcard. * backend/pas/pas-backend-card-sexp.h: add prototype for pas_backend_card_sexp_match_ecard. * backend/idl/addressbook.idl: the card removal stuff now takes CardIdList. * backend/ebook/e-book.c (e_book_get_static_capabilities): cache successful capability queries (since they're static). (e_book_check_static_capability): new, convenience function to check if a particular capability is supported. (e_book_remove_card_by_id): build a single element GList and call e_book_remove_cards. (e_book_remove_cards): build up a CORBA sequence from the GList and call Book::removeCards. (e_book_dispose): free the cached capabilities string. * backend/ebook/e-book.h: add new prototypes for e_book_check_static_capability and e_book_remove_cards. * backend/ebook/e-book-view.h (struct _EBookViewClass): rename "card_removed" signal to "cards_removed". * backend/ebook/e-book-view.c (e_book_view_do_removed_event): id -> ids, and free the id list. (e_book_view_check_listener_queue): CardRemovedEvent -> CardsRemovedEvent. * backend/ebook/e-book-view-listener.c (e_book_view_listener_queue_response): free the id list. (e_book_view_listener_queue_idlist_event): new function, used for cards_removed. (e_book_view_listener_queue_status_event): id -> ids. (e_book_view_listener_queue_sequence_event): same. (e_book_view_listener_queue_message_event): same. (impl_BookViewListener_notify_cards_removed): call queue_idlist_event. (e_book_view_listener_dispose): free the id list. (e_book_view_listener_class_init): track change to idl call. * backend/ebook/e-book-view-listener.h (EBookViewListenerOperation): CardRemovedEvent -> CardsRemovedEvent. (EBookViewListenerResponse): char *id -> GList *ids. * backend/ebook/e-book-listener.c (impl_BookListener_respond_r svn path=/trunk/; revision=19854
-rw-r--r--addressbook/backend/idl/addressbook.idl8
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.c22
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.h2
-rw-r--r--addressbook/backend/pas/pas-backend-file.c97
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c31
-rw-r--r--addressbook/backend/pas/pas-backend.c16
-rw-r--r--addressbook/backend/pas/pas-backend.h10
-rw-r--r--addressbook/backend/pas/pas-book-view.c35
-rw-r--r--addressbook/backend/pas/pas-book-view.h2
-rw-r--r--addressbook/backend/pas/pas-book.c31
-rw-r--r--addressbook/backend/pas/pas-book.h8
-rw-r--r--addressbook/backend/pas/pas-card-cursor.c2
-rw-r--r--addressbook/gui/component/addressbook.c3
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.c49
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.h4
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c72
16 files changed, 244 insertions, 148 deletions
diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl
index 84996fe75e..c9ce728a15 100644
--- a/addressbook/backend/idl/addressbook.idl
+++ b/addressbook/backend/idl/addressbook.idl
@@ -15,6 +15,7 @@ module Addressbook {
typedef string CardId;
typedef string VCard;
typedef sequence<VCard> VCardList;
+ typedef sequence<CardId> CardIdList;
typedef sequence<string> stringlist;
interface CardCursor : Bonobo::Unknown {
@@ -44,7 +45,7 @@ module Addressbook {
OtherError
};
void notifyCardAdded (in VCardList cards);
- void notifyCardRemoved (in CardId id);
+ void notifyCardsRemoved (in CardIdList ids);
void notifyCardChanged (in VCardList cards);
void notifySequenceComplete (in CallStatus status);
void notifyStatusMessage (in string message);
@@ -54,6 +55,7 @@ module Addressbook {
};
interface Book : Bonobo::Unknown {
+
/*
* Fetching cards in the addresbook.
*/
@@ -66,7 +68,7 @@ module Addressbook {
* Adding and deleting cards in the book.
*/
void addCard (in VCard vcard);
- void removeCard (in CardId Id);
+ void removeCards (in CardIdList Id);
/*
* Modifying cards in the addressbook.
@@ -153,7 +155,7 @@ module Addressbook {
void notifyCardCreated (in CallStatus status, in CardId Id);
- void notifyCardRemoved (in CallStatus status);
+ void notifyCardsRemoved (in CallStatus status);
void notifyCardModified (in CallStatus status);
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c
index 8c6e2fc003..6c300d8e4f 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.c
+++ b/addressbook/backend/pas/pas-backend-card-sexp.c
@@ -345,15 +345,12 @@ static struct {
};
gboolean
-pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
+pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard)
{
- ECard *card;
ESExpResult *r;
gboolean retval;
- card = e_card_new ((char*)vcard);
- sexp->priv->search_context->card = e_card_simple_new (card);
- g_object_unref(card);
+ sexp->priv->search_context->card = e_card_simple_new (ecard);
/* if it's not a valid vcard why is it in our db? :) */
if (!sexp->priv->search_context->card)
@@ -370,6 +367,21 @@ pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
return retval;
}
+gboolean
+pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
+{
+ ECard *card;
+ gboolean retval;
+
+ card = e_card_new ((char*)vcard);
+
+ retval = pas_backend_card_sexp_match_ecard (sexp, card);
+
+ g_object_unref(card);
+
+ return retval;
+}
+
/**
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h
index e3b4b49c20..eb7c7c6641 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.h
+++ b/addressbook/backend/pas/pas-backend-card-sexp.h
@@ -26,6 +26,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <ebook/e-card.h>
#define PAS_TYPE_BACKEND_CARD_SEXP (pas_backend_card_sexp_get_type ())
#define PAS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExp))
@@ -49,5 +50,6 @@ PASBackendCardSExp *pas_backend_card_sexp_new (const char *text);
GType pas_backend_card_sexp_get_type (void);
gboolean pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard);
+gboolean pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard);
#endif /* __PAS_BACKEND_CARD_SEXP_H__ */
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
index 852352191d..29524eff26 100644
--- a/addressbook/backend/pas/pas-backend-file.c
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -337,6 +337,16 @@ vcard_matches_search (const PASBackendFileBookView *view, char *vcard_string)
return pas_backend_card_sexp_match_vcard (view->card_sexp, vcard_string);
}
+static gboolean
+ecard_matches_search (const PASBackendFileBookView *view, ECard *card)
+{
+ /* If this is not a search context view, it doesn't match be default */
+ if (view->card_sexp == NULL)
+ return FALSE;
+
+ return pas_backend_card_sexp_match_ecard (view->card_sexp, card);
+}
+
static void
pas_backend_file_search (PASBackendFile *bf,
PASBook *book,
@@ -552,7 +562,7 @@ pas_backend_file_changes (PASBackendFile *bf,
for (v = ctx->del_ids; v != NULL; v = v->next){
char *id = v->data;
- pas_book_view_notify_remove (view->book_view, id);
+ pas_book_view_notify_remove_1 (view->book_view, id);
}
pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
@@ -679,59 +689,76 @@ pas_backend_file_process_create_card (PASBackend *backend,
}
static void
-pas_backend_file_process_remove_card (PASBackend *backend,
- PASBook *book,
- PASRemoveCardRequest *req)
+pas_backend_file_process_remove_cards (PASBackend *backend,
+ PASBook *book,
+ PASRemoveCardsRequest *req)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
EIterator *iterator;
- char *vcard_string;
const char *id;
+ GList *l;
+ GList *removed_cards = NULL;
+ GNOME_Evolution_Addressbook_BookListener_CallStatus rv = GNOME_Evolution_Addressbook_BookListener_Success;
- id = req->id;
- string_to_dbt (id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+ for (l = req->ids; l; l = l->next) {
+ id = l->data;
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
+ string_to_dbt (id, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
+ if (0 != db_error) {
+ rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ continue;
+ }
- db_error = db->del (db, NULL, &id_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
+ db_error = db->del (db, NULL, &id_dbt, 0);
+ if (0 != db_error) {
+ rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ continue;
+ }
- db_error = db->sync (db, 0);
- if (db_error != 0)
- g_warning ("db->sync failed.\n");
+ removed_cards = g_list_prepend (removed_cards, e_card_new (vcard_dbt.data));
+ }
+ /* if we actually removed some, try to sync */
+ if (removed_cards) {
+ db_error = db->sync (db, 0);
+ if (db_error != 0)
+ g_warning ("db->sync failed.\n");
+ }
- vcard_string = vcard_dbt.data;
for (iterator = e_list_get_iterator (bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
const PASBackendFileBookView *view = e_iterator_get(iterator);
- if (vcard_matches_search (view, vcard_string)) {
+ GList *view_removed = NULL;
+ for (l = removed_cards; l; l = l->next) {
+ ECard *removed_card = l->data;
+ if (ecard_matches_search (view, removed_card)) {
+ view_removed = g_list_prepend (view_removed, (char*)e_card_get_id (removed_card));
+ }
+ }
+ if (view_removed) {
bonobo_object_ref (BONOBO_OBJECT (view->book_view));
- pas_book_view_notify_remove (view->book_view, req->id);
+ pas_book_view_notify_remove (view->book_view, view_removed);
pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
bonobo_object_unref (BONOBO_OBJECT (view->book_view));
+ g_list_free (view_removed);
}
}
g_object_unref(iterator);
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success);
- pas_backend_summary_remove_card (bf->priv->summary, id);
+ pas_book_respond_remove (book, rv);
+
+ for (l = removed_cards; l; l = l->next) {
+ ECard *c = l->data;
+ pas_backend_summary_remove_card (bf->priv->summary, e_card_get_id (c));
+ g_object_unref (c);
+ }
+
+ g_list_free (removed_cards);
}
static void
@@ -801,7 +828,7 @@ pas_backend_file_process_modify_card (PASBackend *backend,
else if (new_match)
pas_book_view_notify_add_1 (view->book_view, req->vcard);
else /* if (old_match) */
- pas_book_view_notify_remove (view->book_view, id);
+ pas_book_view_notify_remove_1 (view->book_view, id);
pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
@@ -1417,7 +1444,7 @@ pas_backend_file_get_uri (PASBackend *backend)
static char *
pas_backend_file_get_static_capabilities (PASBackend *backend)
{
- return g_strdup("local,do-initial-query,cache-completions");
+ return g_strdup("local,do-initial-query,bulk-removes");
}
static gboolean
@@ -1487,7 +1514,7 @@ pas_backend_file_class_init (PASBackendFileClass *klass)
parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
parent_class->create_card = pas_backend_file_process_create_card;
- parent_class->remove_card = pas_backend_file_process_remove_card;
+ parent_class->remove_cards = pas_backend_file_process_remove_cards;
parent_class->modify_card = pas_backend_file_process_modify_card;
parent_class->check_connection = pas_backend_file_process_check_connection;
parent_class->get_vcard = pas_backend_file_process_get_vcard;
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
index ff6632e382..3e0db0fca5 100644
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ b/addressbook/backend/pas/pas-backend-ldap.c
@@ -456,20 +456,20 @@ check_schema_support (PASBackendLDAP *bl)
continue;
for (j = 0; oc->oc_names[j]; j++)
- if (!g_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) {
+ if (!g_ascii_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) {
g_print ("support found on ldap server for objectclass evolutionPerson\n");
bl->priv->evolutionPersonSupported = TRUE;
add_oc_attributes_to_supported_fields (bl, oc);
}
- else if (!g_strcasecmp (oc->oc_names[j], CALENTRY)) {
+ else if (!g_ascii_strcasecmp (oc->oc_names[j], CALENTRY)) {
g_print ("support found on ldap server for objectclass calEntry\n");
bl->priv->calEntrySupported = TRUE;
add_oc_attributes_to_supported_fields (bl, oc);
}
- else if (!g_strcasecmp (oc->oc_names[j], INETORGPERSON)
- || !g_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON)
- || !g_strcasecmp (oc->oc_names[j], PERSON)) {
+ else if (!g_ascii_strcasecmp (oc->oc_names[j], INETORGPERSON)
+ || !g_ascii_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON)
+ || !g_ascii_strcasecmp (oc->oc_names[j], PERSON)) {
add_oc_attributes_to_supported_fields (bl, oc);
}
@@ -1349,7 +1349,7 @@ remove_card_handler (LDAPOp *op, LDAPMessage *res)
bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
- pas_book_view_notify_remove (view->book_view, remove_op->id);
+ pas_book_view_notify_remove_1 (view->book_view, remove_op->id);
bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
@@ -1378,9 +1378,9 @@ remove_card_dtor (LDAPOp *op)
}
static void
-pas_backend_ldap_process_remove_card (PASBackend *backend,
- PASBook *book,
- PASRemoveCardRequest *req)
+pas_backend_ldap_process_remove_cards (PASBackend *backend,
+ PASBook *book,
+ PASRemoveCardsRequest *req)
{
LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1390,7 +1390,12 @@ pas_backend_ldap_process_remove_card (PASBackend *backend,
book_view = find_book_view (bl);
- remove_op->id = g_strdup (req->id);
+ /*
+ ** since we didn't pass "bulk-removes" in our static
+ ** capabilities, we should only get 1 length lists here, so
+ ** the id we're deleting is the first and only id in the list.
+ */
+ remove_op->id = g_strdup (req->ids->data);
do {
book_view_notify_status (book_view, _("Removing card from LDAP server..."));
@@ -1476,7 +1481,7 @@ modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
else if (new_match)
pas_book_view_notify_add_1 (view->book_view, modify_op->vcard);
else /* if (old_match) */
- pas_book_view_notify_remove (view->book_view, e_card_simple_get_id (modify_op->card));
+ pas_book_view_notify_remove_1 (view->book_view, e_card_simple_get_id (modify_op->card));
pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
@@ -3384,7 +3389,7 @@ pas_backend_ldap_get_uri (PASBackend *backend)
return bl->priv->uri;
}
-static char *
+static char*
pas_backend_ldap_get_static_capabilities (PASBackend *backend)
{
return g_strdup("net");
@@ -3484,7 +3489,7 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities;
parent_class->create_card = pas_backend_ldap_process_create_card;
- parent_class->remove_card = pas_backend_ldap_process_remove_card;
+ parent_class->remove_cards = pas_backend_ldap_process_remove_cards;
parent_class->modify_card = pas_backend_ldap_process_modify_card;
parent_class->check_connection = pas_backend_ldap_process_check_connection;
parent_class->get_vcard = pas_backend_ldap_process_get_vcard;
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index b47afd8d30..31d6752d82 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -80,17 +80,17 @@ pas_backend_create_card (PASBackend *backend,
}
void
-pas_backend_remove_card (PASBackend *backend,
- PASBook *book,
- PASRemoveCardRequest *req)
+pas_backend_remove_cards (PASBackend *backend,
+ PASBook *book,
+ PASRemoveCardsRequest *req)
{
g_return_if_fail (PAS_IS_BACKEND (backend));
g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->id != NULL);
+ g_return_if_fail (req != NULL && req->ids != NULL);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_card != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_cards != NULL);
- return (* PAS_BACKEND_GET_CLASS (backend)->remove_card) (backend, book, req);
+ return (* PAS_BACKEND_GET_CLASS (backend)->remove_cards) (backend, book, req);
}
void
@@ -250,8 +250,8 @@ process_client_requests (PASBook *book, gpointer user_data)
pas_backend_create_card (backend, book, &req->create);
break;
- case RemoveCard:
- pas_backend_remove_card (backend, book, &req->remove);
+ case RemoveCards:
+ pas_backend_remove_cards (backend, book, &req->remove);
break;
case ModifyCard:
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index a87e28c2a2..b33518116e 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -53,9 +53,9 @@ typedef struct {
void (*remove_client) (PASBackend *backend, PASBook *book);
char *(*get_static_capabilities) (PASBackend *backend);
- void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req);
- void (*remove_card) (PASBackend *backend, PASBook *book, PASRemoveCardRequest *req);
- void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req);
+ void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req);
+ void (*remove_cards) (PASBackend *backend, PASBook *book, PASRemoveCardsRequest *req);
+ void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req);
void (*check_connection) (PASBackend *backend, PASBook *book, PASCheckConnectionRequest *req);
void (*get_vcard) (PASBackend *backend, PASBook *book, PASGetVCardRequest *req);
void (*get_cursor) (PASBackend *backend, PASBook *book, PASGetCursorRequest *req);
@@ -92,9 +92,9 @@ gboolean pas_backend_is_writable (PASBackend *backen
void pas_backend_create_card (PASBackend *backend,
PASBook *book,
PASCreateCardRequest *req);
-void pas_backend_remove_card (PASBackend *backend,
+void pas_backend_remove_cards (PASBackend *backend,
PASBook *book,
- PASRemoveCardRequest *req);
+ PASRemoveCardsRequest *req);
void pas_backend_modify_card (PASBackend *backend,
PASBook *book,
PASModifyCardRequest *req);
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
index 52af28c3bb..fce4173f0f 100644
--- a/addressbook/backend/pas/pas-book-view.c
+++ b/addressbook/backend/pas/pas-book-view.c
@@ -64,20 +64,47 @@ pas_book_view_notify_change_1 (PASBookView *book_view,
* pas_book_view_notify_remove:
*/
void
-pas_book_view_notify_remove (PASBookView *book_view,
- const char *id)
+pas_book_view_notify_remove_1 (PASBookView *book_view,
+ const char *id)
{
+ GList *ids = NULL;
+
+ ids = g_list_prepend (ids, (char*)id);
+
+ pas_book_view_notify_remove (book_view, ids);
+
+ g_list_free (ids);
+}
+
+void
+pas_book_view_notify_remove (PASBookView *book_view,
+ const GList *ids)
+{
+ GNOME_Evolution_Addressbook_CardIdList idlist;
CORBA_Environment ev;
+ const GList *l;
+ int num_ids, i;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardRemoved (
- book_view->priv->listener, (GNOME_Evolution_Addressbook_CardId) id, &ev);
+ num_ids = g_list_length ((GList*)ids);
+ idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids);
+ idlist._maximum = num_ids;
+ idlist._length = num_ids;
+
+ for (l = ids, i = 0; l; l=l->next, i ++) {
+ idlist._buffer[i] = CORBA_string_dup (l->data);
+ }
+
+ GNOME_Evolution_Addressbook_BookViewListener_notifyCardsRemoved (
+ book_view->priv->listener, &idlist, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n");
}
+ CORBA_free(idlist._buffer);
+
CORBA_exception_free (&ev);
}
diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h
index ec6517e394..dd6c74c596 100644
--- a/addressbook/backend/pas/pas-book-view.h
+++ b/addressbook/backend/pas/pas-book-view.h
@@ -47,6 +47,8 @@ void pas_book_view_notify_change (PASBookView *b
void pas_book_view_notify_change_1 (PASBookView *book_view,
const char *card);
void pas_book_view_notify_remove (PASBookView *book_view,
+ const GList *ids);
+void pas_book_view_notify_remove_1 (PASBookView *book_view,
const char *id);
void pas_book_view_notify_add (PASBookView *book_view,
const GList *cards);
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
index 2cb373b9d7..dc626e59e1 100644
--- a/addressbook/backend/pas/pas-book.c
+++ b/addressbook/backend/pas/pas-book.c
@@ -80,13 +80,19 @@ pas_book_queue_create_card (PASBook *book, const char *vcard)
}
static void
-pas_book_queue_remove_card (PASBook *book, const char *id)
+pas_book_queue_remove_cards (PASBook *book,
+ const GNOME_Evolution_Addressbook_CardIdList *ids)
{
PASRequest *req;
-
+ int i;
+
req = g_new0 (PASRequest, 1);
- req->op = RemoveCard;
- req->remove.id = g_strdup (id);
+ req->op = RemoveCards;
+ req->remove.ids = NULL;
+
+ for (i = 0; i < ids->_length; i ++) {
+ req->remove.ids = g_list_append (req->remove.ids, g_strdup (ids->_buffer[i]));
+ }
pas_book_queue_request (book, req);
}
@@ -281,13 +287,13 @@ impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant,
}
static void
-impl_GNOME_Evolution_Addressbook_Book_removeCard (PortableServer_Servant servant,
- const CORBA_char *id,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_removeCards (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CardIdList *ids,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_remove_card (book, (const char *) id);
+ pas_book_queue_remove_cards (book, ids);
}
static void
@@ -512,7 +518,7 @@ pas_book_respond_remove (PASBook *book,
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardRemoved (
+ GNOME_Evolution_Addressbook_BookListener_notifyCardsRemoved (
book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -865,8 +871,9 @@ pas_book_free_request (PASRequest *req)
g_free (req->create.id);
g_free (req->create.vcard);
break;
- case RemoveCard:
- g_free (req->remove.id);
+ case RemoveCards:
+ g_list_foreach (req->remove.ids, (GFunc)g_free, NULL);
+ g_list_free (req->remove.ids);
break;
case ModifyCard:
g_free (req->modify.vcard);
@@ -990,7 +997,7 @@ pas_book_class_init (PASBookClass *klass)
epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard;
epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard;
- epv->removeCard = impl_GNOME_Evolution_Addressbook_Book_removeCard;
+ epv->removeCards = impl_GNOME_Evolution_Addressbook_Book_removeCards;
epv->modifyCard = impl_GNOME_Evolution_Addressbook_Book_modifyCard;
epv->checkConnection = impl_GNOME_Evolution_Addressbook_Book_checkConnection;
epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h
index 1474e760f4..761f906437 100644
--- a/addressbook/backend/pas/pas-book.h
+++ b/addressbook/backend/pas/pas-book.h
@@ -32,7 +32,7 @@ typedef struct _PASBookPrivate PASBookPrivate;
typedef enum {
CreateCard,
- RemoveCard,
+ RemoveCards,
ModifyCard,
GetVCard,
GetCursor,
@@ -53,8 +53,8 @@ typedef struct {
typedef struct {
PASOperation op;
- char *id;
-} PASRemoveCardRequest;
+ GList *ids;
+} PASRemoveCardsRequest;
typedef struct {
PASOperation op;
@@ -112,7 +112,7 @@ typedef union {
PASOperation op;
PASCreateCardRequest create;
- PASRemoveCardRequest remove;
+ PASRemoveCardsRequest remove;
PASModifyCardRequest modify;
PASGetVCardRequest get_vcard;
PASGetCursorRequest get_cursor;
diff --git a/addressbook/backend/pas/pas-card-cursor.c b/addressbook/backend/pas/pas-card-cursor.c
index 8450a45028..9637bb1fb7 100644
--- a/addressbook/backend/pas/pas-card-cursor.c
+++ b/addressbook/backend/pas/pas-card-cursor.c
@@ -108,6 +108,8 @@ pas_card_cursor_construct (PASCardCursor *cursor,
g_return_if_fail (cursor != NULL);
g_return_if_fail (PAS_IS_CARD_CURSOR (cursor));
+ priv = cursor->priv;
+
priv->get_length = get_length;
priv->get_nth = get_nth;
priv->data = data;
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
index 5baaa05733..7e43be131c 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/gui/component/addressbook.c
@@ -124,8 +124,7 @@ delete_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view) {
- if (e_contact_editor_confirm_delete (GTK_WINDOW (view->view)))
- e_addressbook_view_delete_selection(view->view);
+ e_addressbook_view_delete_selection(view->view);
}
}
diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c
index 1d5b228bac..df537cbdf7 100644
--- a/addressbook/gui/widgets/e-addressbook-model.c
+++ b/addressbook/gui/widgets/e-addressbook-model.c
@@ -197,24 +197,42 @@ create_card(EBookView *book_view,
static void
remove_card(EBookView *book_view,
- const char *id,
+ GList *ids,
EAddressbookModel *model)
{
- int i;
+ int i = 0;
+ int num_deleted = 0;
+ GList *l;
+
+ /* XXX this is really broken. the CARD_REMOVED signal should
+ be enough for us, but the !(*@#& EReflow mess can't delete
+ single objects at a time. In fact it can't remove objects
+ at all. every deletion = model_changed. */
+ for (l = ids; l; l = l->next) {
+ char *id = l->data;
+ for ( i = 0; i < model->data_count; i++) {
+ if ( !strcmp(e_card_get_id(model->data[i]), id) ) {
+ g_object_unref (model->data[i]);
+ memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
+ model->data_count--;
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_get_id(model->data[i]), id) ) {
- g_object_unref (model->data[i]);
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
- model->data_count--;
-
- g_signal_emit (model,
- e_addressbook_model_signals [CARD_REMOVED], 0,
- i);
- update_folder_bar_message (model);
- break;
+ num_deleted++;
+ break;
+ }
}
}
+
+ if (num_deleted == 1) {
+ g_signal_emit (model,
+ e_addressbook_model_signals [CARD_REMOVED], 0,
+ i);
+ update_folder_bar_message (model);
+ }
+ else if (num_deleted > 1) {
+ g_signal_emit (model,
+ e_addressbook_model_signals [MODEL_CHANGED], 0);
+ update_folder_bar_message (model);
+ }
}
static void
@@ -480,9 +498,7 @@ get_view (EAddressbookModel *model)
{
if (model->book && model->query) {
if (model->first_get_view) {
- char *capabilities;
- capabilities = e_book_get_static_capabilities (model->book);
- if (capabilities && strstr (capabilities, "do-initial-query")) {
+ if (e_book_check_static_capability (model->book, "do-initial-query")) {
e_book_get_book_view (model->book, model->query, book_view_loaded, model);
} else {
remove_book_view(model);
@@ -493,7 +509,6 @@ get_view (EAddressbookModel *model)
e_addressbook_model_signals [STOP_STATE_CHANGED], 0);
}
model->first_get_view = FALSE;
- g_free (capabilities);
}
else
e_book_get_book_view (model->book, model->query, book_view_loaded, model);
diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h
index 4863c62e07..c5d9e6ca84 100644
--- a/addressbook/gui/widgets/e-addressbook-model.h
+++ b/addressbook/gui/widgets/e-addressbook-model.h
@@ -31,7 +31,9 @@ struct _EAddressbookModel {
int data_count;
int allocated_count;
- int create_card_id, remove_card_id, modify_card_id, status_message_id, writable_status_id, sequence_complete_id, backend_died_id;
+ int create_card_id, remove_card_id, modify_card_id;
+ int status_message_id, writable_status_id, sequence_complete_id;
+ int backend_died_id;
guint search_in_progress : 1;
guint editable : 1;
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index c13baa4a95..db1636693a 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -746,21 +746,42 @@ delete (GtkWidget *widget, CardAndBook *card_and_book)
{
if (e_contact_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(card_and_book->view->widget)))) {
EBook *book;
-
GList *list = get_card_list(card_and_book);
GList *iterator;
+ gboolean bulk_remove = FALSE;
+
+ bulk_remove = e_book_check_static_capability (card_and_book->view->model->book,
+ "bulk-remove");
g_object_get(card_and_book->view->model,
"book", &book,
NULL);
- for (iterator = list; iterator; iterator = iterator->next) {
- ECard *card = iterator->data;
- /* Remove the card. */
- e_book_remove_card (book,
- card,
- NULL,
- NULL);
+ if (bulk_remove) {
+ GList *ids = NULL;
+
+ for (iterator = list; iterator; iterator = iterator->next) {
+ ECard *card = iterator->data;
+ ids = g_list_prepend (ids, (char*)e_card_get_id (card));
+ }
+
+ /* Remove the cards all at once. */
+ e_book_remove_cards (book,
+ ids,
+ NULL,
+ NULL);
+
+ g_list_free (ids);
+ }
+ else {
+ for (iterator = list; iterator; iterator = iterator->next) {
+ ECard *card = iterator->data;
+ /* Remove the card. */
+ e_book_remove_card (book,
+ card,
+ NULL,
+ NULL);
+ }
}
e_free_object_list(list);
}
@@ -1735,42 +1756,15 @@ e_addressbook_view_print_preview(EAddressbookView *view)
#endif
}
-static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
- }
-}
-
-static void
-do_remove (int i, gpointer user_data)
-{
- EBook *book;
- ECard *card;
- EAddressbookView *view = user_data;
-
- g_object_get (view->model,
- "book", &book,
- NULL);
-
- card = e_addressbook_model_get_card (view->model, i);
-
- e_book_remove_card(book, card, card_deleted_cb, view);
-
- g_object_unref (card);
-}
-
void
e_addressbook_view_delete_selection(EAddressbookView *view)
{
- ESelectionModel *model = get_selection_model (view);
+ CardAndBook card_and_book;
- g_return_if_fail (model);
+ memset (&card_and_book, 0, sizeof (card_and_book));
+ card_and_book.view = view;
- e_selection_model_foreach (model,
- do_remove,
- view);
+ delete (GTK_WIDGET (view), &card_and_book);
}
static void