aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
commit653cfffc0e00dfb59b36813c1b45c53d3f773c65 (patch)
tree9b486d5e383ec1391d60973d9cc548be0ef6d9d5
parent0fb08f3ff81575a4749d851404233f34252dd2f2 (diff)
downloadgsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.gz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.bz2
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.lz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.xz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.zst
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.zip
Merge new-ui-branch to the trunk.
svn path=/trunk/; revision=22965
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.am1
-rw-r--r--addressbook/ChangeLog2073
-rw-r--r--addressbook/Makefile.am4
-rw-r--r--addressbook/backend/ebook/.cvsignore1
-rw-r--r--addressbook/backend/ebook/Makefile.am114
-rw-r--r--addressbook/backend/ebook/docs/rfc2739.txt899
-rw-r--r--addressbook/backend/ebook/e-book-async.c1120
-rw-r--r--addressbook/backend/ebook/e-book-async.h107
-rw-r--r--addressbook/backend/ebook/e-book-listener.c779
-rw-r--r--addressbook/backend/ebook/e-book-listener.h42
-rw-r--r--addressbook/backend/ebook/e-book-query.c524
-rw-r--r--addressbook/backend/ebook/e-book-query.h49
-rw-r--r--addressbook/backend/ebook/e-book-types.h59
-rw-r--r--addressbook/backend/ebook/e-book-util.c808
-rw-r--r--addressbook/backend/ebook/e-book-util.h94
-rw-r--r--addressbook/backend/ebook/e-book-view-listener.c263
-rw-r--r--addressbook/backend/ebook/e-book-view-listener.h30
-rw-r--r--addressbook/backend/ebook/e-book-view.c101
-rw-r--r--addressbook/backend/ebook/e-book-view.h15
-rw-r--r--addressbook/backend/ebook/e-book.c2549
-rw-r--r--addressbook/backend/ebook/e-book.h212
-rw-r--r--addressbook/backend/ebook/e-card-compare.h72
-rw-r--r--addressbook/backend/ebook/e-card-cursor.c239
-rw-r--r--addressbook/backend/ebook/e-card-cursor.h53
-rw-r--r--addressbook/backend/ebook/e-card-pairs.h118
-rw-r--r--addressbook/backend/ebook/e-card-simple.c1344
-rw-r--r--addressbook/backend/ebook/e-card-simple.h234
-rw-r--r--addressbook/backend/ebook/e-card-types.h101
-rw-r--r--addressbook/backend/ebook/e-card.c2807
-rw-r--r--addressbook/backend/ebook/e-card.h209
-rw-r--r--addressbook/backend/ebook/e-contact.c1288
-rw-r--r--addressbook/backend/ebook/e-contact.h227
-rw-r--r--addressbook/backend/ebook/e-destination.h140
-rw-r--r--addressbook/backend/ebook/e-vcard.c488
-rw-r--r--addressbook/backend/ebook/e-vcard.h99
-rw-r--r--addressbook/backend/ebook/test-client-list.c65
-rw-r--r--addressbook/backend/ebook/test-client.c191
-rw-r--r--addressbook/backend/ebook/tests/Makefile.am2
-rw-r--r--addressbook/backend/ebook/tests/ebook/.cvsignore7
-rw-r--r--addressbook/backend/ebook/tests/ebook/Makefile.am12
-rw-r--r--addressbook/backend/ebook/tests/ebook/test-changes.c89
-rw-r--r--addressbook/backend/ebook/tests/ebook/test-date.c36
-rw-r--r--addressbook/backend/ebook/tests/ebook/test-ebook.c110
-rw-r--r--addressbook/backend/ebook/tests/ebook/test-photo.c59
-rw-r--r--addressbook/backend/ebook/tests/ebook/test-string.c27
-rw-r--r--addressbook/backend/ebook/tests/vcard/Makefile.am6
-rw-r--r--addressbook/backend/ebook/tests/vcard/dump-vcard.c2
-rw-r--r--addressbook/backend/idl/addressbook.idl218
-rw-r--r--addressbook/backend/pas/Makefile.am14
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.c239
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.h13
-rw-r--r--addressbook/backend/pas/pas-backend-file.c1315
-rw-r--r--addressbook/backend/pas/pas-backend-file.h6
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c1405
-rw-r--r--addressbook/backend/pas/pas-backend-summary.c80
-rw-r--r--addressbook/backend/pas/pas-backend-summary.h14
-rw-r--r--addressbook/backend/pas/pas-backend-sync.c395
-rw-r--r--addressbook/backend/pas/pas-backend-sync.h81
-rw-r--r--addressbook/backend/pas/pas-backend-vcf.c632
-rw-r--r--addressbook/backend/pas/pas-backend-vcf.h35
-rw-r--r--addressbook/backend/pas/pas-backend.c582
-rw-r--r--addressbook/backend/pas/pas-backend.h119
-rw-r--r--addressbook/backend/pas/pas-book-factory.c260
-rw-r--r--addressbook/backend/pas/pas-book-view.c362
-rw-r--r--addressbook/backend/pas/pas-book-view.h29
-rw-r--r--addressbook/backend/pas/pas-book.c830
-rw-r--r--addressbook/backend/pas/pas-book.h202
-rw-r--r--addressbook/backend/pas/pas-card-cursor.c139
-rw-r--r--addressbook/backend/pas/pas-card-cursor.h56
-rw-r--r--addressbook/backend/pas/pas-marshal.list1
-rw-r--r--addressbook/backend/pas/pas-types.h32
-rw-r--r--addressbook/backend/pas/ximian-vcard.h81
-rw-r--r--addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in27
-rw-r--r--addressbook/gui/component/Makefile.am21
-rw-r--r--addressbook/gui/component/addressbook-component.c653
-rw-r--r--addressbook/gui/component/addressbook-component.h45
-rw-r--r--addressbook/gui/component/addressbook-config.c16
-rw-r--r--addressbook/gui/component/addressbook.c216
-rw-r--r--addressbook/gui/component/addressbook.h4
-rw-r--r--addressbook/gui/component/component-factory.c29
-rw-r--r--addressbook/gui/component/e-address-popup.h88
-rw-r--r--addressbook/gui/component/e-address-widget.c568
-rw-r--r--addressbook/gui/component/e-address-widget.h82
-rw-r--r--addressbook/gui/component/e-cardlist-model.c239
-rw-r--r--addressbook/gui/component/e-cardlist-model.h42
-rw-r--r--addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl72
-rw-r--r--addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in4
-rw-r--r--addressbook/gui/component/select-names/Makefile.am4
-rw-r--r--addressbook/gui/component/select-names/e-select-names-bonobo.c41
-rw-r--r--addressbook/gui/component/select-names/e-select-names-completion.c238
-rw-r--r--addressbook/gui/component/select-names/e-select-names-completion.h2
-rw-r--r--addressbook/gui/component/select-names/e-select-names-manager.c27
-rw-r--r--addressbook/gui/component/select-names/e-select-names-model.c181
-rw-r--r--addressbook/gui/component/select-names/e-select-names-model.h27
-rw-r--r--addressbook/gui/component/select-names/e-select-names-popup.c96
-rw-r--r--addressbook/gui/component/select-names/e-select-names-table-model.c18
-rw-r--r--addressbook/gui/component/select-names/e-select-names-text-model.c65
-rw-r--r--addressbook/gui/component/select-names/e-select-names.c83
-rw-r--r--addressbook/gui/component/select-names/e-select-names.h2
-rw-r--r--addressbook/gui/component/select-names/e-simple-card-bonobo.c216
-rw-r--r--addressbook/gui/component/select-names/e-simple-card-bonobo.h71
-rw-r--r--addressbook/gui/contact-editor/Makefile.am2
-rw-r--r--addressbook/gui/contact-editor/contact-editor.glade43
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-address.c16
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-address.h6
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-fullname.c34
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-fullname.h6
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c765
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h40
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.c60
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.h4
-rw-r--r--addressbook/gui/contact-editor/e-contact-save-as.c218
-rw-r--r--addressbook/gui/contact-editor/e-contact-save-as.h41
-rw-r--r--addressbook/gui/contact-list-editor/contact-list-editor.glade2
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c460
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.h26
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.c32
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.h15
-rw-r--r--addressbook/gui/merging/.cvsignore1
-rw-r--r--addressbook/gui/merging/Makefile.am17
-rw-r--r--addressbook/gui/merging/e-card-merging.c198
-rw-r--r--addressbook/gui/merging/e-card-merging.h29
-rw-r--r--addressbook/gui/merging/eab-contact-commit-duplicate-detected.glade (renamed from addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade)12
-rw-r--r--addressbook/gui/merging/eab-contact-compare.c (renamed from addressbook/backend/ebook/e-card-compare.c)356
-rw-r--r--addressbook/gui/merging/eab-contact-compare.h73
-rw-r--r--addressbook/gui/merging/eab-contact-duplicate-detected.glade (renamed from addressbook/gui/merging/e-card-duplicate-detected.glade)12
-rw-r--r--addressbook/gui/merging/eab-contact-merging.c197
-rw-r--r--addressbook/gui/merging/eab-contact-merging.h30
-rw-r--r--addressbook/gui/search/e-addressbook-search-dialog.c38
-rw-r--r--addressbook/gui/search/e-addressbook-search-dialog.h31
-rw-r--r--addressbook/gui/widgets/.cvsignore4
-rw-r--r--addressbook/gui/widgets/Makefile.am115
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.c382
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.h83
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.c152
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.h11
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.c207
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.h32
-rw-r--r--addressbook/gui/widgets/e-addressbook-treeview-adapter.c6
-rw-r--r--addressbook/gui/widgets/e-addressbook-util.h65
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c1147
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.etspec30
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h153
-rw-r--r--addressbook/gui/widgets/e-minicard-control.h8
-rw-r--r--addressbook/gui/widgets/e-minicard-label.c4
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.c49
-rw-r--r--addressbook/gui/widgets/e-minicard-view.c48
-rw-r--r--addressbook/gui/widgets/e-minicard-widget-test.c117
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.c264
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.h76
-rw-r--r--addressbook/gui/widgets/e-minicard.c264
-rw-r--r--addressbook/gui/widgets/e-minicard.h6
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c486
-rw-r--r--addressbook/gui/widgets/eab-contact-display.h61
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c (renamed from addressbook/gui/widgets/e-addressbook-util.c)397
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h70
-rw-r--r--addressbook/gui/widgets/eab-marshal.list (renamed from addressbook/gui/widgets/e-addressbook-marshal.list)0
-rw-r--r--addressbook/gui/widgets/eab-popup-control.c (renamed from addressbook/gui/component/e-address-popup.c)425
-rw-r--r--addressbook/gui/widgets/eab-popup-control.h85
-rw-r--r--addressbook/gui/widgets/eab-vcard-control.c (renamed from addressbook/gui/widgets/e-minicard-control.c)235
-rw-r--r--addressbook/gui/widgets/eab-vcard-control.h8
-rw-r--r--addressbook/gui/widgets/test-minicard-label.c129
-rw-r--r--addressbook/gui/widgets/test-minicard-view.c203
-rw-r--r--addressbook/gui/widgets/test-minicard.c120
-rw-r--r--addressbook/printing/Makefile.am6
-rw-r--r--addressbook/printing/e-contact-print-envelope.c31
-rw-r--r--addressbook/printing/e-contact-print-envelope.h4
-rw-r--r--addressbook/printing/e-contact-print.c327
-rw-r--r--addressbook/printing/e-contact-print.h6
-rw-r--r--addressbook/tools/Makefile.am25
-rwxr-xr-xaddressbook/tools/csv2vcard236
-rw-r--r--addressbook/tools/evolution-addressbook-abuse.c127
-rw-r--r--addressbook/tools/evolution-addressbook-clean.in24
-rw-r--r--addressbook/tools/evolution-addressbook-import.c90
-rw-r--r--addressbook/util/.cvsignore4
-rw-r--r--addressbook/util/Makefile.am41
-rw-r--r--addressbook/util/eab-book-util.c293
-rw-r--r--addressbook/util/eab-book-util.h69
-rw-r--r--addressbook/util/eab-destination.c1569
-rw-r--r--addressbook/util/eab-destination.h128
-rw-r--r--addressbook/util/eab-marshal.list5
-rw-r--r--calendar/ChangeLog2071
-rw-r--r--calendar/cal-client/.cvsignore2
-rw-r--r--calendar/cal-client/Makefile.am7
-rw-r--r--calendar/cal-client/cal-client-types.h26
-rw-r--r--calendar/cal-client/cal-client.c3710
-rw-r--r--calendar/cal-client/cal-client.h101
-rw-r--r--calendar/cal-client/cal-listener.c895
-rw-r--r--calendar/cal-client/cal-listener.h53
-rw-r--r--calendar/cal-client/cal-marshal.list6
-rw-r--r--calendar/cal-client/cal-query.c470
-rw-r--r--calendar/cal-client/cal-query.h37
-rw-r--r--calendar/cal-client/client-test.c155
-rw-r--r--calendar/cal-client/query-listener.c393
-rw-r--r--calendar/cal-client/query-listener.h44
-rw-r--r--calendar/cal-util/cal-util.c24
-rw-r--r--calendar/conduits/calendar/calendar-conduit.c125
-rw-r--r--calendar/conduits/todo/todo-conduit.c101
-rw-r--r--calendar/gui/GNOME_Evolution_Calendar.server.in.in26
-rw-r--r--calendar/gui/Makefile.am5
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.c209
-rw-r--r--calendar/gui/alarm-notify/alarm-queue.c2
-rw-r--r--calendar/gui/calendar-commands.c157
-rw-r--r--calendar/gui/calendar-commands.h2
-rw-r--r--calendar/gui/calendar-component.c849
-rw-r--r--calendar/gui/calendar-component.h48
-rw-r--r--calendar/gui/calendar-offline-handler.c18
-rw-r--r--calendar/gui/comp-editor-factory.c46
-rw-r--r--calendar/gui/comp-util.c46
-rw-r--r--calendar/gui/control-factory.c18
-rw-r--r--calendar/gui/control-factory.h2
-rw-r--r--calendar/gui/dialogs/Makefile.am3
-rw-r--r--calendar/gui/dialogs/alarm-options.c34
-rw-r--r--calendar/gui/e-cal-model-calendar.c10
-rw-r--r--calendar/gui/e-cal-model-tasks.c14
-rw-r--r--calendar/gui/e-cal-model.c282
-rw-r--r--calendar/gui/e-cal-model.h2
-rw-r--r--calendar/gui/e-cal-view.c497
-rw-r--r--calendar/gui/e-cal-view.h13
-rw-r--r--calendar/gui/e-calendar-table.c38
-rw-r--r--calendar/gui/e-calendar-view.c497
-rw-r--r--calendar/gui/e-calendar-view.h13
-rw-r--r--calendar/gui/e-day-view.c352
-rw-r--r--calendar/gui/e-day-view.h7
-rw-r--r--calendar/gui/e-itip-control.c162
-rw-r--r--calendar/gui/e-meeting-list-view.c101
-rw-r--r--calendar/gui/e-meeting-model.c1780
-rw-r--r--calendar/gui/e-meeting-model.h116
-rw-r--r--calendar/gui/e-meeting-store.c36
-rw-r--r--calendar/gui/e-meeting-time-sel.c6
-rw-r--r--calendar/gui/e-select-names-editable.c18
-rw-r--r--calendar/gui/e-tasks.c128
-rw-r--r--calendar/gui/e-week-view-event-item.c7
-rw-r--r--calendar/gui/e-week-view.c173
-rw-r--r--calendar/gui/e-week-view.h8
-rw-r--r--calendar/gui/gnome-cal.c617
-rw-r--r--calendar/gui/gnome-cal.h18
-rw-r--r--calendar/gui/itip-utils.c53
-rw-r--r--calendar/gui/main.c28
-rw-r--r--calendar/gui/migration.c126
-rw-r--r--calendar/gui/migration.h30
-rw-r--r--calendar/gui/print.c31
-rw-r--r--calendar/gui/tag-calendar.c3
-rw-r--r--calendar/gui/tasks-control.c4
-rw-r--r--configure.in13
-rw-r--r--evolution-calendar.pc.in2
247 files changed, 29703 insertions, 24552 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a6110f55f..f1d7482fe9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-10-21 Dan Winship <danw@ximian.com>
+
+ * configure.in (GNOME_COMPILE_WARNINGS): Turn off the annoying
+ "comparison between signed and unsigned" warning in gcc 3.3
+
+ * evolution-calendar.pc.in (Cflags): add
+ -I${privincludedir}/libical
+
2003-10-08 Frederic Crozat <fcrozat@mandrakesoft.com>
* configure.in: Check for gnome-thumbnail.h existence.
diff --git a/Makefile.am b/Makefile.am
index 1915b78db7..43368cdf25 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,7 +36,6 @@ SUBDIRS = \
filter \
addressbook \
calendar \
- my-evolution \
art \
composer \
mail \
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index ed3992ba42..881c16f422 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,893 @@
+2003-10-20 Dan Winship <danw@ximian.com>
+
+ * backend/pas/pas-book-view.c: Queue up removes and modifies as
+ well as adds, and remove the calls that took a list of changes
+ rather than a single change, since no one was really using the
+ list versions. Keep a list of IDs currently in the view so we can
+ more easily figure out what changes count as adds, modifies, and
+ removes.
+ (send_pending_adds): Don't reset next_threshold if it's being
+ called from notify_add.
+ (send_pending_changes, send_pending_removes): New
+ (pas_book_view_notify_update): Simplified add/change interface.
+ Takes an EContact and figures out if it's new, modified, or
+ removed relative to this view.
+ (pas_book_view_notify_change, pas_book_view_notify_change_1,
+ pas_book_view_notify_add, pas_book_view_notify_add_1): Gone.
+ (pas_book_view_notify_remove): Now does what remove_1 used to do.
+ (pas_book_view_vcard_matches): Remove this; no longer used.
+
+ * backend/pas/pas-backend.c (pas_backend_notify_update): New.
+ Calls pas_book_view_notify_update() on each of the backend's views.
+ (pas_backend_notify_remove): Likewise for notify_remove().
+ (pas_backend_notify_complete): And notify_complete().
+
+ * backend/pas/pas-book.c (pas_book_respond_create): Take an
+ EContact instead of an id and a vcard. Use
+ pas_backend_notify_update.
+ (pas_book_respond_remove_contacts): Use pas_backend_notify_remove.
+ (pas_book_respond_modify): Take a single EContact instead of two
+ vcards. Use pas_backend_notify_update.
+
+ * backend/pas/pas-backend-sync.c
+ (pas_backend_sync_create_contact): Return an EContact rather than
+ an id.
+ (pas_backend_sync_modify_contact): Return an EContact rather than
+ the old_vcard.
+ (_pas_backend_create_contact, _pas_backend_modify_contact): Update
+
+ * backend/pas/pas-backend-file.c (do_summary_query): Use
+ pas_book_view_notify_update.
+ (pas_backend_file_search_timeout): Likewise
+ (pas_backend_file_create_contact): Update for API changes
+ (pas_backend_file_modify_contact): Likewise.
+
+ * backend/pas/pas-backend-ldap.c (create_contact_handler,
+ pas_backend_ldap_process_create_contact): Update for API changes
+ (modify_contact_modify_handler, modify_contact_search_handler,
+ pas_backend_ldap_process_modify_contact): Likewise
+ (ldap_search_handler): Use pas_book_view_notify_update
+
+ * backend/pas/pas-backend-vcf.c (foreach_search_compare): Use
+ pas_book_view_notify_update.
+ (pas_backend_vcf_process_create_contact): Update for API changes
+ (pas_backend_vcf_process_modify_contact): Likewise
+
+ * backend/pas/pas-backend-summary.c
+ (pas_backend_summary_add_contact): Take an EContact instead of a
+ const char *vcard.
+
+ * backend/ebook/e-contact.c (photo_getter): s/malloc/g_malloc/
+
+ * backend/ebook/tests/ebook/Makefile.am:
+ * backend/ebook/tests/vcard/Makefile.am: Make these automake-1.7
+ compliant
+
+2003-10-20 JP Rosevear <jpr@ximian.com>
+
+ * backend/pas/pas-backend-vcf.c (pas_backend_vcf_search): compiler
+ with non-c99 compilers
+
+2003-10-17 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-contact.c (fn_getter): new function, just return
+ the full name value.
+ (fn_setter): rather distasteful hack. set the N attribute if it's
+ not already present.
+ (n_setter): set the X-EVOLUTION-FILE-AS attribute if it's not
+ already set.
+
+ * backend/pas/pas-backend-ldap.c (prop_info): add PROP_WRITE_ONLY
+ flag for properties (right now just 'sn') that we don't want to
+ use when building the EContact - we only use it when storing the
+ contact out to the ldap server.
+ (build_contact_from_entry): skip WRITE_ONLY properties.
+
+2003-10-17 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/e-addressbook-view.c (init_collection): add the
+ minicard factory back in.
+ (display_view): add the minicard case back in.
+ (get_selection_model): same.
+ (minicard_right_click): resurrect.
+ (create_minicard_view): same.
+ (change_view_type): add the minicard case back in.
+ (eab_view_print): same.
+ (eab_view_print_preview): same.
+
+ * gui/widgets/e-addressbook-view.h (EABViewType): add MINICARD
+ back in.
+
+ * gui/widgets/e-addressbook-model.c (eab_model_new):
+ E_TYPE_AB_MODEL -> EAB_TYPE_MODEL.
+
+ * gui/widgets/e-addressbook-model.h: rename E_TYPE_AB_MODEL to
+ EAB_TYPE_MODEL.
+
+ * gui/widgets/Makefile.am (libeabwidgets_la_SOURCES): add the
+ minicard stuff back into the build.
+
+ * gui/widgets/e-addressbook-reflow-adapter.[ch],
+ gui/widgets/e-minicard-label.[ch],
+ gui/widgets/e-minicard-view-widget.[ch],
+ gui/widgets/e-minicard-view.[ch], gui/widgets/e-minicard.[ch],
+ gui/widgets/gal-view-factory-minicard.[ch], gal-view-minicard.h:
+ resurrect the minicard stuff, in a new uneditable,
+ EContact-friendly state. no in-place editing anymore.
+
+
+2003-10-10 Chris Toshok <toshok@ximian.com>
+
+ * gui/contact-editor/e-contact-editor.c (fill_in_info): un-ifdef
+ the date handling code.
+ (extract_info): same.
+
+ * backend/pas/pas-backend-ldap.c (prop_info): add the address
+ labels and dates to the build.
+ (anniversary_populate): un-ifdef and get this working.
+ (anniversary_ber): same.
+ (anniversary_compare): same.
+ (birthday_populate): same.
+ (birthday_ber): same.
+ (birthday_compare): same.
+
+ * backend/ebook/tests/ebook/.cvsignore,
+ backend/ebook/tests/ebook/Makefile.am
+ backend/ebook/tests/ebook/test-date.c: add a test for EContactDate
+ getting/setting.
+
+ * backend/ebook/e-vcard.h: add EVC_BDAY.
+
+ * backend/ebook/e-contact.h: add prototypes for the
+ e_contact_date_* functions.
+
+ * backend/ebook/e-contact.c (field_info): add
+ BIRTH_DATE/ANNIVERSARY fields.
+ (date_getter): new
+ (date_setter): new
+ (e_contact_date_new): new
+ (e_contact_date_from_string): new
+ (e_contact_date_to_string): new
+ (e_contact_date_free): new
+
+2003-10-10 Not Zed <NotZed@Ximian.com>
+
+ *
+ gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in:
+ Use the main factory on the .so file, so it can be found.
+
+2003-10-08 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/select-names/e-select-names.c (contact_key): add a
+ descriptive comment about this "#if notyet".
+
+ * gui/component/select-names/e-select-names-model.h
+ (e_select_names_model_thaw): add prorotype for
+ e_select_names_model_cancel_all_contact_load.
+
+ * gui/component/select-names/e-select-names-bonobo.c
+ (_EntryPropertyID): remove the SIMPLE_CARD_LIST property.
+ (entry_get_property_fn): same.
+ (impl_SelectNames_get_entry_for_section): same.
+
+ * backend/ebook/e-contact.h: add prototype for
+ e_contact_name_to_string.
+
+2003-10-07 Chris Toshok <toshok@ximian.com>
+
+ * util/eab-book-util.c: remove a bunch of ifdef'ed code (that's
+ going to be living in e-book.c)
+
+ * backend/pas/pas-backend-summary.c
+ (pas_backend_summary_add_contact): un-ifdef some code.
+ (pas_backend_summary_get_summary_vcard): same.
+
+ * backend/pas/pas-backend-ldap.c (prop_info): remove the
+ query_prop field since we can get it from e_contact_field_name.
+ also remove it from all the macros and their uses.
+ (homephone_populate): un-ifdef.
+ (homephone_ber): same.
+ (homephone_compare): same.
+ (business_populate): same.
+ (business_ber): same.
+ (business_compare): same.
+ (query_prop_to_ldap): use e_contact_field_name to get the query
+ prop for a given attribute.
+ (add_oc_attributes_to_supported_fields): same.
+
+ * backend/pas/pas-backend-card-sexp.c (compare_phone): use the new
+ EContactField constants to iterate over the phone list.
+
+ * backend/ebook/e-contact.h (EContactField): add some useful
+ constants for those pieces of code that iterate over
+ email/phones/addresses.
+
+2003-10-07 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/eab-vcard-control.c (book_open_cb): un-ifdef this.
+ (eab_vcard_control_new): put the buttons above the vcard so they
+ don't move when it's expanded.
+
+ * gui/widgets/eab-popup-control.h: remove prototypes for
+ eab_popup_control_set_name and eab_popup_control_set_email.
+
+ * gui/widgets/eab-popup-control.c (email_table_ok_cb): remove the
+ stupid idle function and do the work here.
+ (eab_popup_control_set_name): make this static - noone uses it.
+ (eab_popup_control_set_email): same.
+
+ * gui/widgets/eab-gui-util.c (eab_show_contact_editor):
+ e_contact_editor_new is what we use for the time being.
+
+ * gui/widgets/eab-contact-display.c (render_string): abstract this
+ code out.
+ (render_url): same.
+ (eab_contact_display_render_normal): make use of render_string and
+ render_url.
+
+ * gui/widgets/e-addressbook-view.c (delete): un-ifdef this and get
+ it working.
+ (selection_received): same.
+
+ * gui/widgets/e-addressbook-model.c (get_view): nuke some code
+ that was moved to another function.
+ (eab_model_set_property): get the writable state when we set the
+ book - don't rely on the timing of signals.
+
+ * gui/contact/editor/contact-editor.glade: add the blog field
+ below the homepage url field.
+
+ * gui/contact/editor/e-contact-editor-address.[ch]: get this
+ building with the new stuff.
+
+ * gui/contact/editor/e-contact-editor-fullname.[ch]: get this
+ building with the new stuff.
+
+ * gui/contact-editor/e-contact-editor.[ch]: get this most of the
+ way there.
+
+ * gui/contact-editor/e-contact-quick-add.[ch]: get this building
+ with the new stuff.
+
+ * gui/contact-editor/Makefile.am (libecontacteditor_la_SOURCES):
+ remove e-contact-save-as.[ch]. They're in
+ addressbook/widgets/eab-gui-util.[ch] now.
+
+ * gui/merging/Makefile.am: track all the naming changes.
+
+ * gui/merging/*.glade: gratuitous renaming.
+
+ * gui/merging/eab-contact-compare.[ch]: gratuitous renaming, and
+ move this from the old ebook/
+
+ * gui/merging/eab-contact-merging.[ch]: gratuitous renaming.
+
+ * backend/ebook/e-contact.[ch]: lots of overly complicated changes
+ for an overly complicated piece of code.
+
+ * backend/ebook/e-book-view.c (e_book_view_do_added_event): remove
+ some ifdef'ed code.
+ (e_book_view_do_modified_event): same.
+
+ * backend/ebook/e-vcard.c (parse): plug a memory leak.
+ (escape_string): deal with @s being NULL.
+ (e_vcard_remove_attribute): new function.
+ (e_vcard_attribute_remove_params): same.
+ (e_vcard_attribute_param_free): same.
+ (e_vcard_attribute_param_remove_values): same.
+
+ * backend/ebook/e-vcard.h: add prototypes for
+ e_vcard_remove_attribute, e_vcard_attribute_remove_params, and
+ e_vcard_attribute_param_remove_values.
+
+ * backend/ebook/e-book.c (e_book_handle_response): cache the
+ writable state of the ebook before generating the signal.
+ (e_book_unload_uri): initialize cap to NULL and writable to FALSE.
+
+ * backend/ebook/e-book.h: add prototype for e_book_is_writable.
+
+ * backend/ebook/e-book-async.c (_get_fields_response_handler):
+ don't call the callback if it's NULL.
+ (_get_methods_response_handler): same.
+ (_auth_user_response_handler): same.
+ (_get_contact_response_handler): same.
+ (_remove_contacts_response_handler): same.
+ (_add_contact_response_handler): same.
+ (_commit_contact_response_handler): same.
+ (_get_book_view_response_handler): same.
+ (_get_contacts_response_handler): same.
+ (_remove_contacts_dtor): free the list.
+ (e_book_async_remove_contacts): duplicate the list.
+
+ * backend/pas/pas-backend.c (pas_backend_open): if we successfully
+ load the uri, report the writable status back.
+
+ * backend/pas/pas-backend-sync.c (_pas_backend_remove_contacts):
+ free the list of ids.
+
+ * backend/pas/pas-backend-file.c (do_create): return the contact
+ we create here.
+ (pas_backend_file_create_contact): format the newly created
+ contact as a string to add to the summary.
+ (pas_backend_file_remove_contacts): don't free the list of removed
+ cards here - it happens in pas-backend-sync.
+ (pas_backend_file_load_uri): pass NULL for @contact to do_create.
+
+2003-10-01 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/eab-contact-display.c (render_address): move the :'s
+ inside the <b>'s. Thanks for pointing this out, guenther. :)
+ (eab_contact_display_render_normal): same.
+ (eab_contact_display_render_compact): same.
+
+ * gui/widgets/eab-vcard-control.c (save_in_addressbook): track
+ change to address_load_default_book.
+
+2003-10-01 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/Makefile.am: remove some commented out crap about
+ e-address-popup.[ch].
+
+ * gui/component/component-factory.c (factory): use
+ eab_popup_control_new for the AddressPopup iid.
+
+ * gui/widgets/Makefile.am (libeabwidgets_la_SOURCES): add
+ eab-popup-control.[ch].
+
+ * backend/ebook/e-book.c (e_book_get_default_addressbook): hack
+ this so it at least sorta works - hardcode the
+ ~/evolution/local/Contacts uri for now.
+
+ * gui/component/addressbook.[ch] (addressbook_load_default_book):
+ remove the EBook argument, and call
+ e_book_async_get_default_addressbook.
+
+ * gui/component/e-address-popup.[ch]: nuke.
+
+ * gui/widgets/eab-popup-control.c: rename
+ gui/component/e-address-popup.c to this.
+
+ * gui/widgets/eab-popup-control.h: rename
+ gui/component/e-address-popup.h to this.
+
+ * backend/ebook/e-book-async.h: add prototype for
+ e_book_async_get_default_addressbook.
+
+ * backend/ebook/e-book-async.c
+ (e_book_async_get_default_addressbook): new function.
+
+2003-10-01 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/e-addressbook-view.c (eab_view_new): create the
+ scrolled window to embed the EABContactDisplay widget inside of.
+
+ * gui/widgets/e-addressbook-view.h (struct _EABView): add scrolled;
+
+ * gui/widgets/eab-contact-display.h: add
+ EABContactDisplayRenderMode enum, and add @render_mode arg to
+ eab_contact_display_render.
+
+ * gui/widgets/eab-contact-display.c
+ (eab_contact_display_render_compact): new function, render a
+ compact format suitable for inclusion in the mail display.
+ (eab_contact_display_render_normal): move the previouw contents of
+ eab_contact_display_render here.
+ (eab_contact_display_render): render in either compact or normal
+ mode depending on @mode.
+ (eab_contact_display_new): remove the scrolled window stuff from
+ here, as in the compact mode we don't want it present. push it up
+ into the e-addressbook-view.c code.
+
+ * gui/widgets/eab-vcard-control.[ch]: bonobo control that wraps up
+ the EABContactDisplay stuff and lets us display vcards in a pretty
+ format in mail messages.
+
+ * gui/component/component-factory.c (factory): replace the #if
+ notyet'ed minicard control code with the new vcard control.
+
+ * gui/component/Makefile.am (INCLUDES): remove gui/minicard.
+
+ * gui/component/GNOME_Evolution_Addressbook.server.in.in: remove
+ the MiniCard_Control iid, and replace it with VCard_Control.
+
+2003-10-01 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/addressbook-component.c
+ (destination_folder_handle_drop): use
+ eab_contact_list_from_string, and un-"#if notyet" this.
+
+ * gui/component/addressbook.c: remove #include
+ "e-contact-save-as.h"
+
+ * gui/contact-list-editor/e-contact-list-editor.c
+ (file_save_as_cb): use eab_contact_save.
+ (file_send_as_cb): use eab_send_contact, un-"#if notyet" this.
+ (file_send_to_cb): same.
+ (table_drag_data_received_cb): use eab_contact_list_from_string.
+
+ * gui/widgets/e-addressbook-reflow-adapter.[ch]: nuke. last
+ vestiges of the minicard view.
+
+ * gui/widgets/e-addressbook-view.c (eab_view_init):
+ s/clipboard_cards/cliboard_contacts.
+ (eab_view_dispose): same.
+ (get_contact_list_1): s/card/contact
+ (get_contact_list): same.
+ (save_as): same, and use eab_contact_list_save.
+ (send_as): reenable this code, s/card/contact, and use
+ eab_send_contact_list.
+ (send_to): same.
+ (print): s/card/contact.
+ (delete): same.
+ (new_card): same, and un-"#if notyet" some code.
+ (selection_get): use eab_contact_list_to_string.
+ (selection_clear_event): s/card/contact
+ (selection_received): same.
+ (get_selected_contacts): same.
+ (eab_view_save_as): same, and use eab_contact_list_save.
+ (eab_view_view): same, and use eab_show_multiple_contacts.
+ (eab_view_send): reenable this code, s/card/contact, and use
+ eab_send_contact_list.
+ (eab_view_send_to): same.
+ (eab_view_copy): s/card/contact.
+ (view_transfer_contacts): same.
+ (eab_view_copy_to_folder): same.
+ (eab_view_move_to_folder): same.
+
+ * gui/widgets/e-addressbook-view.h (struct _EABView): rename
+ clipboard_cards to clipboard_contacts.
+
+ * gui/widgets/eab-gui-util.c (view_contacts): un-"#if notyet"
+ (file_exists): moved from e-contact-save-as.c
+ (save_it): same.
+ (close_it): same.
+ (destroy_it): same.
+ (make_safe_filename): same.
+ (eab_contact_save): same, and renamed from e_contact_save_as.
+ (eab_contact_list_save): same, and renamed from
+ e_contact_list_save_as.
+ (contact_deleted_cb): s/card/contact.
+ (do_delete): same, and use e_book_async.
+ (delete_contacts): s/card/contact.
+ (process_unref): same.
+ (contact_added_cb): same.
+ (do_copy): same, and use e_book_async.
+ (got_book_cb): same.
+ (eab_transfer_contacts): same, and use e_book_async.
+ (eab_send_contact_list): s/card/contact
+ (eab_send_contact): same.
+
+ * gui/widgets/eab-gui-util.h: some random s/card/contact work, and
+ move the contents of e-contact-save-as.h here.
+
+ * util/eab-book-util.c (eab_contact_list_from_string): rename
+ eab_load_contacts_from_string to this.
+ (eab_contact_list_to_string): new function.
+
+ * util/eab-book-util.h: add prototype for
+ eab_contact_list_to_string, and rename
+ eab_load_contacts_from_string to eab_contact_list_from_string.
+
+ * gui/contact-editor/e-contact-save-as.[ch]: nuke. the contents
+ of these files has been wrapped up in
+ gui/widgets/eab-gui-util.[ch].
+
+2003-09-30 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/Makefile.am (libevolution_addressbook_la_LIBADD):
+ add libecontactlisteditor.la back into the build.
+
+ * gui/component/addressbook-component.c (new_item_cb): enable the
+ contact list editor portion.
+
+ * util/eab-book-util.c (eab_load_contacts_from_string): new
+ function, return a GList of EContact*'s parsed from the string.
+
+ * util/eab-book-util.h: add prototype for
+ eab_load_contacts_from_string.
+
+ * gui/contact-list-editor/contact-list-editor.glade: set the id of
+ the list-image widget.
+
+ * gui/contact-list-editor/e-contact-list-editor.c
+ (e_contact_list_editor_class_init): PROP_CARD -> PROP_CONTACT.
+ (e_contact_list_editor_init): initialize image_buf to null and
+ card -> contact. also, hook up the dnd signals on the list_image
+ widget so we can drop images.
+ (e_contact_list_editor_dispose): free the image_buf.
+ (list_added_cb): card -> contact.
+ (list_modified_cb): same.
+ (save_contact): same, and use the ebook-async api.
+ (prompt_to_save_changes): card -> contact.
+ (file_save_cb): same.
+ (file_save_as_cb): same.
+ (file_send_as_cb): #if notyet for now.
+ (file_send_to_cb): same.
+ (tb_save_and_close_cb): card -> contact.
+ (list_deleted_cb): same.
+ (delete_cb): same.
+ (delete_cb): same, and use ebook-async.
+ (e_contact_list_editor_new): card -> contact.
+ (e_contact_list_editor_set_property): same.
+ (table_drag_motion_cb): use GDK_POINTER_TO_ATOM instead of
+ casting.
+ (table_drag_data_received_cb): use eab_load_contacts_from_string,
+ and card -> contact.
+ (set_image_from_data): new function. create a pixbuf from the
+ image data and composite it in an image that's the same size as
+ the initial list_image widget.
+ (image_drag_motion_cb): new function.
+ (image_drag_drop_cb): new function.
+ (image_drag_data_received_cb): new function.
+ (extract_info): port to EContact, and add support for the image.
+ (fill_in_info): same.
+
+ * gui/contact-list-editor/e-contact-list-editor.h (struct
+ _EContactListEditor): add image stuff, and ECard -> EContact.
+
+ * gui/contact-list-editor/e-contact-list-model.c
+ (contact_list_value_at): e_destination -> eab_destination.
+ (e_contact_list_model_init): same.
+ (e_contact_list_model_add_destination): same.
+ (e_contact_list_model_add_email): same.
+ (e_contact_list_model_add_contact): same, and card -> contact.
+ (e_contact_list_model_remove_row): e_destination ->
+ eab_destination.
+ (e_contact_list_model_get_destination): same.
+
+ * gui/contact-list-editor/e-contact-list-model.h: card -> contact,
+ and e-destination -> eab-destination.
+
+ * gui/widgets/e-addressbook-view.etspec: fix a couple of
+ fields.. this needs a completely once-over at some point soon.
+
+ * gui/widgets/e-addressbook-view.c (table_double_click): reenable
+ all of this.
+
+ * gui/widgets/eab-contact-display.c (render_address): use
+ e_text_to_html to convert the \n's to <br>'s.
+ (on_url_requested): get PHOTO if there is one, otherwise LOGO.
+ (eab_contact_display_render): escape all the text we're sending to
+ gtkhtml with e_text_to_html. also, if it's a contact list, output
+ _("List Members") with the contents of _EMAIL.
+
+ * gui/widgets/eab-gui-util.h: rename eab_send_card{_list} to
+ eab_send_contact{_list}.
+
+2003-09-30 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/tests/ebook/Makefile.am (noinst_PROGRAMS): add
+ test-string.
+
+ * backend/ebook/tests/ebook/test-string.c: test setting/getting a
+ string attribute.
+
+ * backend/ebook/e-contact.c (photo_setter): do gnome-vfs mime type
+ sniffing before we set the attribute value.
+ (e_contact_set_property): implement setting of MULTI list
+ attributes (like MAIL).
+ (e_contact_get_property): rework the ATTR_TYPE attribute handling
+ so we aren't calling g_value_set_pointer on a value that holds a
+ string (and vice versa).
+
+ * backend/ebook/e-vcard.c (e_vcard_remove_attributes): implement.
+ (e_vcard_attribute_add_param): use g_ascii_strcasecmp.
+
+ * backend/ebook/e-vcard.h: rename e_vcard_remove_attribute to
+ e_vcard_remove_attributes, since it removes all matching
+ attributes.
+
+ * backend/ebook/e-book.c (e_book_response_add_contact): we need to
+ strdup the id here since the listener frees it.
+ (e_book_handle_response): implement the WritableStatusEvent part
+ of the switch.
+
+ * backend/ebook/e-book-listener.c
+ (impl_BookListener_report_writable): un-"#if notyet" this.
+
+ * backend/ebook/e-book-async.c (_add_contact_handler): fill in
+ response->id.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * printing/e-contact-print-envelope.c: card -> contact.
+
+ * printing/e-contact-print-envelope.h: card -> contact.
+
+ * printing/e-contact-print.c: card -> contact.
+
+ * printing/e-contact-print.h: card -> contact.
+
+ * printing/Makefile.am (contact_print_test_LDADD): add
+ libeabutil.la and reorder things so it links.
+ (contact_print_style_editor_test_LDADD): same.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/select-names/e-select-names-text-model.c:
+ e-addressbook-util.h -> eab-gui-util.h.
+
+ * gui/component/select-names/e-select-names-popup.c:
+ e-addressbook-util.h -> eab-gui-util.h.
+
+ * gui/component/e-address-popup.c: e-addressbook-util.h ->
+ eab-gui-util.h.
+
+ * gui/component/component-factory.c: #if notyet the minicard
+ control stuff, since it's been completely nuked from the tree.
+
+ * gui/component/addressbook.c: e-addressbook-util.h ->
+ eab-gui-util.h.
+
+ * gui/component/addressbook-component.c: e-addressbook-util.h ->
+ eab-gui-util.h.
+
+ * gui/component/Makefile.am (libevolution_addressbook_la_LIBADD):
+ rename libeminicard to libeabwidgets.
+
+ * Makefile.am (SUBDIRS): add util/ to the build.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/e-addressbook-treeview-adapter.c:
+ e-addressbook-util.h -> eab-gui-util.h, and convert some
+ EDestination code to EABDestination.
+
+ * gui/widgets/e-addressbook-table-adapter.c: e-addressbook-util.h
+ -> eab-gui-util.h, and include util/eab-destination.h.
+ (addressbook_value_at): un-#if 0 some code.
+
+ * gui/widgets/e-addressbook-model.c: e-addressbook-util.h ->
+ eab-gui-util.h
+
+ * gui/widgets/e-addressbook-view.c: e-addressbook-util.h ->
+ eab-gui-util.h
+
+ * gui/widgets/e-minicard-control.c,
+ gui/widgets/e-minicard-control.h, gui/widgets/e-minicard-label.c,
+ gui/widgets/e-minicard-label.h,
+ gui/widgets/e-minicard-view-widget.c,
+ gui/widgets/e-minicard-view-widget.h,
+ gui/widgets/e-minicard-view.c, gui/widgets/e-minicard-view.h,
+ gui/widgets/e-minicard-widget-test.c,
+ gui/widgets/e-minicard-widget.c, gui/widgets/e-minicard-widget.h,
+ gui/widgets/e-minicard.c, gui/widgets/e-minicard.h,
+ test-minicard-label.c, test-minicard-view.c, test-minicard.c: nuke
+ all of the old minicard stuff.
+
+ * gui/widgets/eab-gui-util.[ch]: rename e-addressbook-util.[ch] to
+ this and nuke e-addressbook-util.[ch].
+
+ * gui/widgets/Makefile.am (INCLUDES): change G_LOG_DOMAIN to
+ eab-widgets, and add -I$(top_srcdir)/addressbook.
+ (noinst_LTLIBRARIES): rename to libeabwidgets.la
+ (libeabwidgets_la_SOURCES): rename e-addressbook-util.[ch] to
+ eab-gui-util.[ch].
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/eab-contact-display.c (eab_contact_display_new):
+ track change from E_TYPE_AB_CONTACT_DISPLAY to
+ EAB_TYPE_CONTACT_DISPLAY.
+
+ * gui/widgets/eab-contact-display.h: change from E_* type foo to
+ EAB_* type foo.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/search/e-addressbook-search-dialog.[ch]: convert everything
+ from e_addressbook_search_dialog to eab_search_dialog, and
+ EAddressbookSearchDialog to EABSearchDialog.
+
+ * gui/component/addressbook.c (search_cb):
+ e_addressbook_search_dialog -> eab_search_dialog.
+ (addressbook_search_activated): same.
+ (addressbook_query_changed): same.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book.c (pas_book_respond_get_supported_fields):
+ don't free the fields here - the backends hold onto them.
+ (pas_book_respond_get_supported_auth_methods): don't free the
+ auth_methods here - the backends hold onto them.
+
+ * backend/pas/pas-backend-file.c
+ (pas_backend_file_get_supported_fields): fields go from 1 to
+ E_CONTACT_FIELD_LAST, not 0.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/addressbook.c: e-book-util.h -> eab-book-util.h
+
+ * gui/component/addressbook-component.c: e-book-util.h ->
+ eab-book-util.h.
+ (new_item_cb): enable the contact editor portion of this.
+ (user_create_new_item_cb): convert to async_load_uri api, and
+ ifdef the _use_default_book crap.
+ (ensure_completion_uris_exist): e_book_get_config_database ->
+ eab_get_config_database.
+
+ * gui/component/e-address-widget.h: e-book-util.h ->
+ eab-book-util.h.
+
+ * gui/component/Makefile.am (libevolution_addressbook_la_LIBADD):
+ add selectnames back in, and add util/libeabutil.la.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-contact.c: my head explodes from so many
+ changes.
+
+ * backend/ebook/e-contact.h: reorder fields such that all the
+ string fields are first in the enum (and add a
+ E_CONTACT_LAST_SIMPLE_STRING value, ala the old e-card-simple
+ stuff.) Also, add E_CONTACT_LOGO, WANTS_HTML, IS_LIST, and
+ LIST_SHOW_ADDRESSES. remove E_CONTACT_PHOTO_URI.
+
+ * backend/ebook/e-vcard.c (e_vcard_remove_attribute): rename from
+ e_card_remove_attribute, and add a g_assert_not_reached.
+ (_evc_base64_encode_simple): make this not static (we need it for
+ a test.)
+ (_evc_base64_decode_simple): same.
+
+ * backend/ebook/e-vcard.h: add LOGO, X-MOZILLA-HTML,
+ X-EVOLUTION-LIST, and X-EVOLUTION-LIST-SHOW_ADDRESSES #defines.
+
+ * backend/ebook/e-book.c (EBookLoadState): change from
+ UriNotLoaded to E_BOOK_URI_NOT_LOADED, etc.
+ (e_book_add_contact): track _URI_ change.
+ (e_book_get_supported_fields): same.
+ (e_book_get_supported_auth_methods): same.
+ (e_book_authenticate_user): same.
+ (e_book_get_contact): same.
+ (e_book_response_get_contact): remove the ifdefed call to
+ e_contact_set_book.
+ (e_book_remove_contacts): track _URI_ change.
+ (e_book_get_book_view): same.
+ (e_book_get_contacts): same.
+ (e_book_get_changes): same.
+ (e_book_remove): same.
+ (e_book_unload_uri): same.
+ (e_book_load_uri): same.
+ (e_book_load_uri): same.
+ (e_book_get_self): start the implementation of this.
+ (e_book_get_default_addressbook): ifdef out a possible
+ implementation of this (it's broken.)
+ (e_book_init): track _URI_ change.
+ (e_book_dispose): same.
+
+ * backend/ebook/e-book.h: move get_default_addressbook out of the
+ ifdef, and change get_default_addressbook/get_addressbooks to be
+ more like the rest of the api.
+
+ * backend/ebook/e-book-util.[ch]: nuke.
+
+ * backend/ebook/e-card-compare.[ch]: nuke.
+
+ * backend/ebook/e-destination.[ch]: nuke.
+
+ * backend/ebook/e-book-query.c (func_and): fix valgrind error.
+ (func_or): same.
+
+ * backend/ebook/e-book-listener.h: drop #include of e-list.h
+
+ * backend/ebook/e-book-async.c (_get_contacts_response_handler)
+ (_get_contacts_response_dtor, _get_contacts_handler)
+ (_get_contacts_dtor, e_book_async_get_contacts): new functions,
+ implementing e_book_async_get_contacts.
+
+ * backend/ebook/e-book-async.h: add e_book_async_get_contacts.
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * util/eab-marshal.list: new file.
+
+ * util/eab-destination.[ch]: rename
+ backend/ebook/e-destination.[ch] to this, and change all the entry
+ point names too.
+
+ * util/eab-book-util.[ch]: rename backend/ebook/e-book-util.[ch]
+ to this, and change all the entry point names too.
+
+ * util/Makefile.am: new file, build libeabutil.la
+
+2003-09-29 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/select-names/e-select-names.c
+ (addressbook_model_set_uri): e_addressbook_model -> eab_model.
+ (contact_key): e-contactify this, and remove the call to
+ e_contact_get_book since we don't have it.
+ (sync_one_model): card -> contact.
+ (real_add_address_cb): track various name changes.
+ (esn_get_key_fn): same.
+ (e_addressbook_create_ebook_table): same.
+ (folder_selected): same.
+ (select_entry_changed): same.
+ (e_select_names_new): same.
+
+ * gui/component/select-names/e-select-names-text-model.c
+ (dump_model): s/card/contact.
+ (e_select_names_text_model_insert_length): e-destination ->
+ eab-destination.
+ (e_select_names_text_model_delete): same.
+ (e_select_names_text_model_obj_count): same.
+ (nth_obj_index): same.
+ (e_select_names_text_model_activate_obj): ifdef this out since we
+ don't have e_contact_get_book in the new api.
+
+ * gui/component/select-names/e-select-names-table-model.c
+ (fill_in_info): convert to e_contact/eab_destination.
+
+ * gui/component/select-names/e-select-names-popup.c
+ (change_email_num_cb): e_destination -> eab_destination.
+ (populate_popup_contact): same, and ECard -> EContact. Also, the
+ email attribute is a GList, not an EList. lastly, rename from
+ populate_popup_card.
+ (populate_popup_nocontact): same, and rename from
+ populate_popup_nocard.
+ (e_select_names_populate_popup): same.
+
+ * gui/component/select-names/e-select-names-model.h: track changes
+ to e_destination, and rename the cardify methods to something mode
+ descriptive.
+
+ * gui/component/select-names/e-select-names-model.c
+ (e_select_names_model_duplicate): e_destination ->
+ eab_destination.
+ (e_select_names_model_get_textification): same.
+ (e_select_names_model_get_address_text): same.
+ (e_select_names_model_get_destination): same.
+ (e_select_names_model_export_destinationv): same.
+ (send_changed): same.
+ (e_select_names_model_import_destinationv): same.
+ (e_select_names_model_get_contact): same, and rename from
+ _get_card
+ (e_select_names_model_get_string): same.
+ (connect_destination): same.
+ (disconnect_destination): same.
+ (e_select_names_model_contains): same.
+ (e_select_names_model_insert): same.
+ (e_select_names_model_append): same.
+ (e_select_names_model_replace): same.
+ (e_select_names_model_delete): same.
+ (e_select_names_model_clean): same.
+ (delete_all_iter): same.
+ (e_select_names_model_overwrite_copy): same.
+ (e_select_names_model_merge): same.
+ (e_select_names_model_name_pos): same.
+ (e_select_names_model_text_pos): same.
+ (e_select_names_model_cardify): nuke.
+ (e_select_names_model_uncardify): nuke.
+ (e_select_names_model_cancel_cardify): nuke.
+ (e_select_names_model_load_all_contacts): rename _cardify_all to
+ this.
+ (e_select_names_model_cancel_all_contact_load): rename
+ _cancel_cardify to this.
+
+ * gui/component/select-names/e-select-names-manager.c
+ (focus_in_cb): cancel_cardify_all -> cancel_all_contact_load
+ (focus_out_cb): cardify_all -> load_all_contacts.
+ (completion_popup_cb): same.
+ (load_completion_books): no e_book_expand_uri anymore.
+ (e_select_names_manager_new): e_book_get_config_database ->
+ eab_get_config_database.
+ (e_select_names_manager_dispose): same.
+
+ * gui/component/select-names/e-select-names-completion.h: e-book.h
+ -> e-book-async.h
+
+ * gui/component/select-names/e-select-names-completion.c:
+ EContactify this.
+
+ * gui/component/select-names/e-select-names-bonobo.c
+ (entry_get_property_fn): ifdef out the SIMPLE_CARD_LIST getter,
+ and cardify_all -> load_all_contacts.
+
+ * gui/component/select-names/Evolution-Addressbook-SelectNames.idl:
+ nuke all the SimpleCard stuff. It's a horribly inefficient way to
+ deal with vcards, and since ebook is platform level now, we can
+ (and should) promote just linking to ebook to do this.
+
2003-09-19 Gilbert Fang <gilbert.fang@sun.com>
* addressbook/gui/component/addressbook-component.c (xfer_folder):
@@ -12,17 +902,715 @@
non-static versions of libraries: the static ones were only needed
for libtool 1.3.
+2003-09-07 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-contact.c (e_contact_get_property): implement
+ getters for the address labels. they aren't really synthetic, but
+ we can't handle them as normal strings because they switch off the
+ TYPE parameter, not the attribute name (go go vcard.) Also add
+ getters for the structured address fields (ADR). Also fix a spot
+ where we were using strcmp instead of strcasecmp.
+ (e_contact_address_free): new function.
+
+ * backend/ebook/e-contact.h: Add EContactAddress structure, which
+ will probably go away once i merge in my cool spiffy address
+ editor. Add LABEL fields for the address labels, and add
+ prototype for e_contact_address_free.
+
+ * backend/ebook/e-vcard.h: add EVC_LABEL and EVC_X_BLOG_URL.
+
+ * backend/ebook/e-vcard.c (read_attribute_value): step to the next
+ character after unescaping \-escaped characters. keeps commas
+ from multiplying.
+
+ * gui/widgets/eab-contact-display.c (render_address): new function
+ (eab_contact_display_render): display email, delivery addresses,
+ and the blog url.
+
+2003-09-06 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-contact.c (e_contact_set_property): implement
+ E_CONTACT_EMAIL_*.
+
+ * backend/pas/pas-backend-ldap.c (email_ber): EContact-ify and
+ re-enable this code.
+ (email_compare): same.
+ (email_populate): same.
+
+ * backend/pas/pas-backend-vcf.c (pas_backend_vcf_load_uri): use
+ XIMIAN_VCARD.
+
+ * backend/pas/pas-backend-file.c (pas_backend_file_load_uri): use
+ XIMIAN_VCARD, and don't fail if the directory already exists.
+ just try to create the db anyway.
+
+ * backend/pas/Makefile.am (libpas_a_SOURCES): add ximian-vcard.h
+
+ * backend/pas/ximian-vcard.h (XIMIAN_VCARD): put the initial vcard
+ here, so we can share 1 #define between file/vcf backends. Also,
+ add a jpeg photo.
+
+2003-09-06 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/Makefile.am (libeminicard_la_SOURCES): add
+ eab-contact-display.[ch]
+
+ * gui/widgets/e-addressbook-view.c (eab_view_init): just init
+ everything to NULL.
+ (eab_view_new): move a bunch of stuff that was in eab_view_init
+ here. create a vpaned to hold the contact display, and create the
+ contact display.
+ (render_contact): render the selected contact to the
+ contact_display.
+ (selection_changed): add logic to display the currently selected
+ contact in the preview pane.
+ (create_table_view): add the table to the paned.
+ (create_treeview_view): add the scrolled to the paned.
+ (change_view_type): remove view->widget from the paned.
+
+ * gui/widgets/e-addressbook-view.h: switch from using a GtkTable
+ to a GtkEventBox - we don't need the table logic anymore.
+
+ * gui/widgets/e-addressbook-model.c (create_contact): indent
+ (eab_model_get_contact): same.
+
+ * gui/widgets/eab-contact-display.[ch]: new files - this
+ implements the preview pane.
+
+2003-09-06 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-ldap.c (BINARY_PROP): new type of
+ property, for specifying data coming back from the ldap server
+ with both data/length (like photos).
+ (photo_populate): set the contact's photo.
+ (build_contact_from_entry): add PROP_TYPE_BINARY handling.
+
+ * backend/ebook/e-vcard.c (EVCardEncoding): new enum for use with
+ the ENCODING attribute parameter. Right now, just "raw",
+ "base64", and "quoted-printable".
+ (struct _EVCardAttribute): add a "decoded_values" list of
+ GString*'s, as well as fields to hold encoding/encoding_set.
+ (e_vcard_class_init): call _evc_base64_init.
+ (e_vcard_attribute_add_value_decoded): based on what encoding the
+ attribute uses, add the value properly.
+ (e_vcard_attribute_add_param): if the parameter is ENCODING, work
+ our magic.
+ (e_vcard_attribute_get_values_decoded): spit out properly decoded
+ values depending on the decoding type.
+ (_evc_base64*): copy the camel base64 routines here.
+
+ * backend/ebook/e-vcard.h: add prototypes for
+ e_vcard_attribute_add_value_decoded and
+ e_vcard_attribute_get_values_decoded.
+
+ * backend/ebook/e-contact.c (e_contact_get_first_attr): move this
+ to above _set_property so we can make use of it there.
+ (e_contact_set_property): fix up the generic STRING field handler,
+ and implement E_CONTACT_PHOTO setting.
+ (e_contact_get_property): add handling for
+ E_CONTACT_PHOTO/E_CONTACT_PHOTO_URI.
+ (e_contact_photo_free): new function.
+
+ * backend/ebook/e-contact.h: add EContactPhoto struct, a prototype
+ for e_contact_photo_free, and two new EContactField elements (PHOTO and
+ PHOTO_URI).
+
+ * backend/ebook/tests/ebook/.cvsignore: ignore test-photo
+
+ * backend/ebook/tests/ebook/Makefile.am (noinst_PROGRAMS): add test-photo
+
+ * backend/ebook/tests/ebook/test-photo.c: test for the photo
+ set/get routines (which do base64 encoding/decoding).
+
+2003-09-02 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/Makefile.am: comment out a buncha stuff just to
+ get this building.
+
+ * gui/component/select-names/e-select-names.c: #include
+ e-book-async.h
+ (search_result): EAddressbookModel -> EABModel.
+ (addressbook_model_set_uri): same, and don't use
+ e_book_expand_uri, as it's dead.
+ (esn_get_key_fn): EAddressbookModel -> EABModel.
+ (e_addressbook_create_ebook_table): same.
+ (status_message): same.
+
+ * gui/component/select-names/e-select-names.h (struct
+ _ESelectNames): EAddressbookModel -> EABModel.
+
+ * gui/component/addressbook-component.c (new_item_cb): ifdef out
+ for now.
+ (dnd_drop_book_open_cb): s/card/contact.
+ (destination_folder_handle_drop): ifdef out.
+ (request_quit): same.
+
+ * gui/component/addressbook.c: track api changes - e_addressbook_
+ -> eab_, and e_book_* becomes e_book_async_*.
+
+ * gui/component/addressbook.h: #include e-book-async.h
+
+ * gui/component/e-address-widget.c (query_results_cb):
+ e/EBookSimpleQueryStatus/EBookStatus
+
+ * gui/component/e-address-widget.h: s/ECard/EContact.
+
+ * gui/component/e-cardlist-model.[ch]: nuke.
+
+ * gui/component/e-address-popup.c: s/e-book.h/e-book-async.h
+
+ * gui/component/e-address-popup.h: s/ECard/EContact
+
+2003-09-02 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/Makefile.am (libebook_la_SOURCES): remove
+ e-card.c,e-card.simple.c
+
+ * backend/ebook/tests/ebook/test-ebook.c: remove #include of
+ e-card-simple.h
+
+ * backend/ebook/tests/ebook/test-changes.c: remove #include of
+ e-card-simple.h
+
+ * backend/ebook/e-card.[ch], backend/ebook/e-card-simple.[ch]:
+ nuke.
+
+ * backend/ebook/e-book-util.h: s/card/contact.
+
+ * backend/ebook/e-book-util.c: ifdef out an #include.
+
+ * backend/ebook/e-book-async.[ch]: stop doing the stupid #define
+ renaming trick, and just rename all the prototypes from e_book_*
+ to e_book_async_*. Also, get rid of the *_vcard variants.
+
+2003-09-02 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-card-sexp.[ch]
+ (pas_backend_card_sexp_match_contact): rename
+ pas_backend_card_sexp_match_card, and it takes an EContact now.
+ Also, port this file to use EContact instead of ECard, and ifdef
+ out lots of stuff.
+
+ * backend/pas/pas-backend-ldap.c: convert this to use EContact
+ instead of ECard, and ifdef great swaths of code to make it
+ compile.
+
+ * backend/pas/pas-book.c (pas_book_respond_modify): convert this
+ from ECard to EContact.
+
+2003-09-02 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/Makefile.am (libeminicard_la_SOURCES): remove all
+ the reflow/minicard stuff from the build.
+ (e-addressbook-marshal.[ch]): change the prefix on the marshallers to
+ eab_marshal.
+
+ * gui/widgets/e-addressbook-view.etspec: bring this more in line
+ with the field ids for EContact, and comment out a ton of them
+ that aren't there yet.
+
+ * gui/widgets/e-addressbook-view.[ch]: big renaming - rename
+ e_addressbook_view to eab_view, and EAddressbookView to EABView.
+
+ * gui/widgets/e-addressbook-util.c (eab_error_dialog): rename, and
+ change a few of the error strings s/Card/Contact.
+ (added_cb): E_BOOK_STATUS_SUCCESS => E_BOOK_ERROR_OK.
+ (modified_cb): same.
+ (e_addressbook_show_contact_editor): this takes an EContact now,
+ and track the change to the contact editor signal names.
+ (e_addressbook_show_contact_list_editor): this takes an EContact
+ now.
+ (view_contacts): rename view_cards to this, and ifdef the body.
+ (e_addressbook_show_multiple_contacts): rename
+ e_addressbook_show_multiple_cards to this, and s/card/contact.
+
+ * gui/widgets/e-addressbook-util.h: ifdef some things out, and
+ rename e_addressbook_error_dialog to eab_error_dialog.
+
+ * gui/widgets/e-addressbook-table-adapter.[ch]: big renaming -
+ rename e_addressbook_table_adapter to eab_table_adapter, and
+ EAddressbookTableAdapter to EABTableAdapter. Also, remove the
+ simple mapping - we can do ECardSimple-like operations directly on
+ the EContacts from the EABModel.
+
+ * gui/widgets/e-addressbook-model.[ch]: big renaming - rename
+ e_addressbook_model to eab_model, and EAddressbookModel to
+ EABModel. Also, convert everything from ECard to EContact.
+
+2003-09-01 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-vcard.c (e_vcard_new_from_string): omg i'm dumb.
+ don't call e_vcard_new here since it just turns around and calls
+ e_vcard_new_from_string again.
+
+2003-09-01 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book-view.c (pas_book_view_notify_change): guard
+ pending adds foo.
+ (pas_book_view_notify_remove): same.
+ (pas_book_view_notify_add): same.
+ (pas_book_view_notify_complete): same.
+ (pas_book_view_construct): init mutex
+ (pas_book_view_dispose): free mutex
+
+ * backend/pas/pas-backend-ldap.c (func_exists): new function.
+ (send_pending_adds): remove
+ (ldap_search_handler): let the BookView stuff handle the pending
+ adds for us.
+ (ldap_search_dtor): remove pending adds stuff.
+ (pas_backend_ldap_search): same
+
+ * backend/pas/pas-backend-card-sexp.c (func_exists): new function.
+
+ * backend/ebook/tests/ebook/test-ebook.c (print_all_emails): use
+ an exists query.
+
+2003-08-31 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-query.c (func_and, func_or, func_not)
+ (func_contains, func_is, func_beginswith, func_endswith)
+ (e_book_query_from_string): adapt the pas ldap backend sexp
+ parsing code to this, build up an EBookQuery that represents the
+ sexp.
+
+ * backend/ebook/e-contact.h (e_contact_field_id): add prototype.
+
+ * backend/ebook/e-contact.c (e_contact_field_id): new function.
+
+ * backend/ebook/Makefile.am (libebook_la_SOURCES): add
+ e-book-util.c back into the build, if only for the config_database
+ thingy.
+
+2003-08-31 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-contact.c (e_contact_duplicate): new function.
+
+ * backend/ebook/e-contact.h: add prototype for
+ e_contact_duplicate.
+
+ * backend/ebook/e-book-util.[ch]: massive ifdeffing. most of this
+ is either gone or will be unnecessary soon.
+
+ * backend/ebook/e-book-query.c (e_book_query_from_string): hack
+ this so it'll at least generate a query.
+
+ * backend/ebook/e-book-listener.c
+ (impl_BookListener_respond_get_view): add some debug spew and
+ remove a c&p'ed comment.
+
+ * backend/ebook/e-book-async.h: add prototype for
+ e_book_async_unload_uri.
+
+ * backend/ebook/e-book-async.c (e_book_async_unload_uri): new
+ function.
+
+ * backend/pas/pas-book-view.c (pas_book_view_construct): switch to
+ CORBA_Object_duplicate, ala pas_book.
+
+ * backend/pas/pas-backend-sync.c (pas_backend_sync_class_init):
+ fix typo and the build.
+
+2003-08-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-ldap.c (ldap_error_to_response):
+ s/card/contact.
+ (pas_backend_ldap_process_create_contact): same.
+ (remove_contact_handler): same.
+ (remove_contact_dtor): same.
+ (pas_backend_ldap_process_remove_contacts): same.
+ (modify_contact_modify_handler): same.
+ (modify_contact_dtor): same.
+ (pas_backend_ldap_process_modify_contact): same.
+ (get_contact_handler): same.
+ (get_contact_dtor): same.
+ (pas_backend_ldap_process_get_contact): same.
+ (pas_backend_ldap_class_init): same.
+
+ * backend/pas/pas-backend-summary.c
+ (pas_backend_summary_add_contact): s/card/contact, and mostly
+ switch from ECard{Simple} to EContact.
+ (pas_backend_summary_get_summary_vcard): same.
+ (pas_backend_summary_remove_contact): s/card/contact
+
+ * backend/pas/pas-backend-summary.h: s/card/contact.
+
+ * backend/pas/pas-backend-file.c (build_summary): fix g_warning,
+ and return immediately if the db->cursor call fails.
+ (pas_backend_file_create_contact): s/card/contact
+ (pas_backend_file_remove_contacts): same.
+ (pas_backend_file_modify_contact): same.
+ (pas_backend_file_get_contact): same.
+ (pas_backend_file_get_contact_list): same.
+ (pas_backend_file_class_init): same.
+
+ * backend/pas/pas-backend-vcf.c
+ (pas_backend_vcf_process_create_contact): s/card/contact.
+ (pas_backend_vcf_process_remove_contacts): same.
+ (pas_backend_vcf_process_modify_contact): same.
+ (pas_backend_vcf_process_get_contact): same.
+ (pas_backend_vcf_process_get_contact_list): same.
+ (pas_backend_vcf_class_init): same.
+
+ * backend/pas/pas-backend-sync.c (pas_backend_sync_create_contact): s/card/contact.
+ (pas_backend_sync_remove_contacts): same.
+ (pas_backend_sync_modify_contact): same.
+ (pas_backend_sync_get_contact): same.
+ (pas_backend_sync_get_contact_list): same.
+ (_pas_backend_create_contact): same.
+ (_pas_backend_remove_contacts): same.
+ (_pas_backend_modify_contact): same.
+ (_pas_backend_get_contact): same.
+ (_pas_backend_get_contact_list): same.
+ (pas_backend_sync_class_init): same.
+
+ * backend/pas/pas-backend-sync.h: s/card/contact.
+
+ * backend/pas/pas-backend.c (pas_backend_create_contact): s/card/contact.
+ (pas_backend_remove_contacts): same.
+ (pas_backend_modify_contact): same.
+ (pas_backend_get_contact): same.
+ (pas_backend_get_contact_list): same.
+ (pas_backend_change_add_new): same.
+ (pas_backend_change_modify_new): same.
+ (pas_backend_change_delete_new): same.
+
+ * backend/pas/pas-backend.h: s/card/contact.
+
+ * backend/pas/pas-book-view.c (send_pending_adds): s/card/contact
+ (pas_book_view_notify_change): same.
+ (pas_book_view_notify_remove): same.
+
+ * backend/pas/pas-book.c
+ (impl_GNOME_Evolution_Addressbook_Book_getContact): s/card/contact
+ (impl_GNOME_Evolution_Addressbook_Book_getContactList): same.
+ (impl_GNOME_Evolution_Addressbook_Book_addContact): same.
+ (impl_GNOME_Evolution_Addressbook_Book_removeContacts): same.
+ (impl_GNOME_Evolution_Addressbook_Book_modifyContact): same.
+ (pas_book_respond_create): same.
+ (pas_book_respond_remove_contacts): same.
+ (pas_book_respond_modify): same.
+ (pas_book_respond_get_contact): same.
+ (pas_book_respond_get_contact_list): same.
+ (pas_book_respond_get_changes): same.
+ (pas_book_class_init): same.
+
+ * backend/pas/pas-book.h: s/card/contact
+
+ * backend/ebook/tests/vcard/dump-vcard.c: #include
+ "ebook/e-vcard.h"
+
+ * backend/ebook/tests/vcard/Makefile.am (TEST_LIBS): use
+ top_builddir.
+ (CFLAGS): same.
+
+ * backend/ebook/tests/ebook/Makefile.am (TEST_LIBS): use
+ top_builddir.
+ (CFLAGS): use srcdir
+
+ * backend/ebook/test-card.c, backend/ebook/test-client-list.c,
+ backend/ebook/test-client.c, backend/ebook/test-ebook.c: remove.
+
+ * backend/ebook/e-card-cursor.[ch]: remove.
+
+ * backend/ebook/e-card-pairs.h: remove.
+
+ * backend/ebook/e-book.c (e_book_add_contact): s/Card/Contact.
+ (e_book_commit_contact): same
+ (e_book_get_contact): same.
+ (e_book_remove_contacts): same.
+ (e_book_get_contacts): same.
+ (e_book_handle_response): same.
+
+ * backend/ebook/e-book-view.c (e_book_view_do_added_event):
+ s/card/contact
+ (e_book_view_do_modified_event): same.
+ (e_book_view_do_removed_event): same.
+ (e_book_view_handle_response): same.
+ (e_book_view_class_init): same.
+
+ * backend/ebook/e-book-view.h: s/card/contact and pad the class
+ struct.
+
+ * backend/ebook/e-book-view-listener.c
+ (e_book_view_listener_queue_response): s/Card/Contact.
+ (e_book_view_listener_queue_status_event): no need to assign
+ things to NULL, we g_new0.
+ (e_book_view_listener_queue_idlist_event): s/Card/Contact, and no
+ need to assign things to NULL, we g_new0.
+ (e_book_view_listener_queue_sequence_event): same.
+ (e_book_view_listener_queue_message_event): same.
+ (impl_BookViewListener_notify_contacts_added): s/Card/Contact.
+ (impl_BookViewListener_notify_contacts_removed): same.
+ (impl_BookViewListener_notify_contacts_changed): same.
+ (e_book_view_listener_class_init): same.
+
+ * backend/ebook/e-book-view-listener.h: s/Card/Contact
+
+ * backend/ebook/e-book-types.h: s/CARD/CONTACT
+
+ * backend/ebook/e-book-listener.c
+ (e_book_listener_convert_status): s/Card/Contact
+ (impl_BookListener_respond_create_contact): same.
+ (impl_BookListener_respond_remove_contacts): same.
+ (impl_BookListener_respond_modify_contact): same.
+ (impl_BookListener_respond_get_contact): same.
+ (impl_BookListener_respond_get_contact_list): same.
+ (impl_BookListener_respond_get_changes): same.
+ (e_book_listener_class_init): same.
+
+ * backend/ebook/e-book-listener.h: pad the class struct, and
+ s/Card/Contact.
+
+ * backend/ebook/e-book-async.c (_load_uri_handler): GError
+ changes.
+ (_get_fields_handler): same.
+ (_get_methods_handler): same.
+ (_auth_user_handler): same.
+ (_get_card_handler): same.
+ (_remove_cards_handler): same.
+ (_add_vcard_handler): same.
+ (_commit_vcard_handler): same.
+ (_get_book_view_handler): same.
+ (e_book_async_get_book_view): use an EBookQuery instead of a char*.
+
+ * backend/ebook/Makefile.am: remove the test handling.
+ (SUBDIRS): set to ". tests"
+ (libebook_la_SOURCES): add e-book-async.c
+
+ * backend/idl/addressbook.idl: possibly gratuitous renaming, but i
+ was sick of seeing "Card" being used everywhere. "Contact" is the
+ new "Card".
+
+2003-08-28 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book.c (e_book_op_free): rename from
+ e_book_free_op.
+ (e_book_op_remove): rename from e_book_remove_op.
+ (e_book_clear_op): new function, remove the op, unlock its mutex,
+ and free it.
+ (e_book_add_contact): use e_book_clear_op.
+ (e_book_commit_contact): same.
+ (e_book_get_supported_fields): same.
+ (e_book_get_supported_auth_methods): same.
+ (e_book_authenticate_user): same.
+ (e_book_get_contact): same.
+ (e_book_remove_contacts): same.
+ (e_book_get_book_view): same.
+ (e_book_get_contacts): same.
+ (e_book_get_changes): same.
+ (e_book_load_uri): same.
+ (e_book_remove): new function.
+ (e_book_response_remove): new function.
+ (e_book_handle_response): add handling for RemoveBookResponse.
+ (e_book_load_local_addressbook): pass TRUE for e_book_load_uri
+ @only_if_exists.
+
+ * backend/ebook/e-book.h: add @only_if_exists arg to
+ e_book_load_uri so we can support folder creation at load_uri
+ time, and add prototype for e_book_remove.
+
+ * backend/ebook/e-book-types.h: add an "id" slot in EBookChange.
+
+ * backend/ebook/e-book-listener.c
+ (impl_BookListener_respond_get_changes): handle union in idl.
+ (impl_BookListener_respond_open_book): remove unnecessary
+ exception check.
+ (impl_BookListener_respond_remove_book): new function.
+ (impl_BookListener_respond_get_supported_fields): rename this from
+ _response_.
+ (impl_BookListener_respond_get_supported_auth_methods): same.
+ (e_book_listener_class_init): add _remove_book and track change to
+ get_supported_fields/get_supported_auth_methods names.
+
+ * backend/ebook/e-book-listener.h: add RemoveBookResponse to
+ EBookListenerOperation enum.
+
+ * backend/idl/addressbook.idl: make BookChangeItem a union that
+ switches over BookChangeType.
+
+ * backend/pas/pas-backend.c (pas_backend_change_add_new): new
+ function, create a BookChangeItem representing the addition of a
+ contact.
+ (pas_backend_change_modify_new): same, but for modifications.
+ (pas_backend_change_delete_new): same, but for deletions.
+
+ * backend/pas/pas-backend.h: add prototypes for
+ pas_backend_change_{add,modify,delete}_new
+
+ * backend/pas/pas-backend-file.c (pas_backend_file_changes): nuke.
+ (do_create): fix memory corruption.
+ (pas_backend_file_get_changes): copy the body of
+ pas_backend_file_changes here, and rework so that it's synchronous
+ and return a list instead of the book view hack.
+ (pas_backend_file_load_uri): mkdir the directory (we need a mkdir
+ -p here).
+ (select_changes): new function, scandir helper.
+ (pas_backend_file_remove): NULL out bf->priv->summary to quiet
+ valgrind, and call scandir to accumulate the .changes.db files
+ then unlink them.
+
+ * backend/pas/pas-book.c (pas_book_respond_remove): new function.
+ (pas_book_respond_get_supported_fields): unifdef this, and make it
+ use a glist.
+ (pas_book_respond_get_supported_auth_methods): same.
+ (pas_book_respond_get_changes): this code is kinda gross... lots
+ of copying going on, there's got to be a better way. but it
+ works.
+
+2003-08-26 Chris Toshok <toshok@ximian.com>
+
+ * backend/idl/addressbook.idl: add oneway void Book::remove() and
+ oneway void notifyBookRemoved()
+
+2003-08-26 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend.c (pas_backend_remove): new function.
+ (pas_backend_add_book_view): new function.
+ (pas_backend_add_client): move the "real_add_client" code here.
+ (pas_backend_remove_client): move the "real_remove_client" code
+ here.
+ (pas_backend_class_init): remove assignments of add_client and
+ remove_client vtable entries.
+ (pas_backend_is_removed): new function.
+ (pas_backend_set_is_removed): new function.
+ (pas_backend_init): init clients_mutex and views_mutex.
+
+ * backend/pas/pas-backend.h: remove the vtable entries for
+ add/remove_client, since these are fully handled in PASBackend.
+ Add prototypes for
+ pas_backend_is_removed/pas_backend_add_book_view/pas_backend_set_is_removed.
+
+ * backend/pas/pas-book.c
+ (impl_GNOME_Evolution_Addressbook_Book_remove): new function.
+ (impl_GNOME_Evolution_Addressbook_Book_getBookView): clean things
+ up a bit, and don't use pas_backend_get_book_views as it can't
+ lock the list of views.
+ (pas_book_respond_get_supported_auth_methods): remove the extra
+ unnecessary arg from the corba call.
+ (pas_book_respond_get_changes): same.
+ (pas_book_class_init): fill in epv "remove" slot.
+
+ * backend/pas/pas-book.h: rename pas_book_respond_remove to
+ pas_book_respond_remove_cards, and add a new
+ pas_book_respond_remove for use with removing books.
+
+ * backend/pas/pas-backend-sync.c (pas_backend_sync_remove): new
+ function.
+ (_pas_backend_remove): new function.
+ (pas_backend_sync_class_init): fill in the "remove" vtable entry.
+ (_pas_backend_remove_cards): track change to
+ pas_book_respond_remove_cards (pas_book_respond_remove is used for
+ removing the book, not the cards.)
+
+ * backend/pas/pas-backend-sync.h: add pas_backend_sync_remove
+ prototype and add remove_sync virtual function.
+
+2003-08-26 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-file.c (pas_backend_file_create_card,
+ pas_backend_file_remove_cards, pas_backend_file_modify_card,
+ pas_backend_file_get_vcard, pas_backend_file_get_card_list,
+ pas_backend_file_start_book_view, pas_backend_file_get_changes,
+ pas_backend_file_authenticate_user,
+ pas_backend_file_get_supported_fields): rename from
+ pas_backend_file_process_*
+ (pas_backend_file_load_uri): save off the dirname/summary
+ filename.
+ (pas_backend_file_remove): new function, unlink all the files we
+ know about.
+ (pas_backend_file_class_init): track changes to functions, and add
+ pas_backend_file_remove.
+
2003-08-26 JP Rosevear <jpr@ximian.com>
- * conduit/address-conduit.c (ecard_from_remote_record): duplicate
+ * conduit/address-conduit.c (ecard_from_remote_record): duplicate
the extra address lines
+2003-08-22 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book.[ch]: switch from using the PASRequest
+ union and a central PASBackend dispatch function. just call the
+ pas_backend methods directly and expand the args out.
+
+ * backend/pas/pas-backend.[ch]: same.
+
+ * backend/pas/pas-backend-sync.[ch]: same.
+
+ * backend/pas/pas-backend-vcf.c, backend/pas/pas-backend-file.c,
+ backend/pas/pas-backend-ldap.c: same, and get these all compiling
+ against the rest of the current pas/ebook code.
+
+2003-08-21 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/test-ebook.c: track GError case.
+
+ * backend/ebook/e-book.[ch]: GError-ify the api, and clean up some
+ cases where we weren't removing the current op.
+
+ * backend/ebook/e-book-view-listener.c
+ (e_book_view_listener_convert_status): track change from
+ E_BOOK_VIEW_STATUS_* to E_BOOK_VIEW_ERROR_*.
+
+ * backend/ebook/e-book-types.h: track change from E_BOOK_STATUS_*
+ to E_BOOK_ERROR_*, and some E_BOOK_VIEW_STATUS_* to
+ E_BOOK_VIEW_ERROR_*.
+
+ * backend/ebook/e-book-listener.c
+ (e_book_listener_convert_status): track change from
+ E_BOOK_STATUS_* to E_BOOK_ERROR_*.
+
+ * backend/ebook/e-book-query.c (e_book_query_any_field_contains):
+ new function.
+ (e_book_query_unref): handle the any_field_contains case.
+ (e_book_query_to_string): same.
+
+ * backend/ebook/e-book-query.h: add prototype for
+ e_book_query_any_field_contains.
+
+ * backend/ebook/e-card.c (e_card_load_uri): ifdef this out for
+ now.
+
+ * backend/ebook/e-contact.[ch] (e_contact_get_const): new
+ function/prototype.
+
2003-08-20 Gilbert Fang <gilbert.fang@sun.com>
- * gui/widgets/e-addressbook-util.c
+ * gui/widgets/e-addressbook-util.c
(e_addressbook_send_card_list): use memcpy to assign
CORBA_char_sequence instead of strcpy. (#46706)
+2003-08-18 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/component/component-factory.c: Update OAFIIDs.
+
+ * gui/widgets/e-addressbook-util.c (e_addressbook_transfer_cards):
+ Removed extern declaration for global_shell_client [yuck].
+ (e_addressbook_transfer_cards): #if 0 the invocation for
+ evolution_shell_client_user_select_folder(), we need to
+ reimplement this component-side now.
+
+ * gui/component/component-factory.c (factory): Call
+ addressbook_component_peek() here instead of
+ addressbook_component_init() [since the latter is no more].
+
+ * gui/component/addressbook.c (set_status_message): Don't create
+ the activity client for now.
+
+ * gui/component/addressbook-config.c: Removed member shell from
+ struct AddressbookDialog.
+ (ldap_dialog_new): Do not take a shell arg anymore.
+ (ldap_config_control_new): Likewise.
+ (addressbook_config_control_new): No need to get the global shell
+ pointer here anymore.
+
+ * gui/component/addressbook-component.c: Rewritten to support the
+ new ::Component interface.
+ * gui/component/addressbook-component.h: Likewise.
+
+ * gui/component/GNOME_Evolution_Addressbook.server.in.in: Version
+ factory's OAFIID. Remove ShellComponent server, add Component
+ server.
+
2003-08-12 Rodrigo Moya <rodrigo@ximian.com>
* backend/ebook/e-book.c (e_book_dispose): unref the
@@ -70,6 +1658,487 @@
* printins/e-contact-print-style-editor.c
(e_contact_print_stule_editor_destroy): Chain. Prevent double unref.
+2003-08-07 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-vcard.c (e_vcard_to_string_vcard_21): new,
+ unimplemented, function.
+ (e_vcard_to_string_vcard_30): move the 3.0 vcard export code here.
+ (e_vcard_to_string): call e_vcard_to_string_vcard_21 or
+ e_vcard_to_string_vcard_30 based on @format.
+ (e_vcard_attribute_remove_values): new function.
+
+ * backend/ebook/e-vcard.h: add @format to e_vcard_to_string, and
+ add prototype for e_vcard_attribute_remove_values. also, add
+ prototype for e_vcard_decode_b_encoding.
+
+2003-08-07 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-listener.c
+ (impl_BookListener_respond_open_book): remove the book arg.
+
+ * backend/ebook/e-book-listener.h (struct _EBookListenerResponse):
+ remove the corba book.
+
+ * backend/ebook/e-book-async.c (_get_book_view_dtor): free the
+ query string.
+ (e_book_async_get_book_view): dup the query string.
+
+ * backend/ebook/e-book.h: change e_book_get_book_view and
+ e_book_get_contacts to take a const char * query string instead of
+ an EBookQuery.
+
+ * backend/ebook/e-book.c (e_book_add_contact): pass
+ EVC_FORMAT_VCARD_30 to e_vcard_to_string.
+ (e_book_commit_contact): same.
+ (e_book_get_book_view): take a const char* query string instead of
+ an EBookQuery.
+ (e_book_get_contacts): same.
+ (e_book_response_open): track change - the Book is no longer
+ communicated back here.
+ (listener_cb): nuke.
+ (e_book_handle_response): track change to e_book_response_open.
+ (e_book_load_uri): rework this from using BookFactory::openBook to
+ BookFactory::getBook + Book::open.
+ (e_book_get_uri): new function, reimplement from old api.
+ (e_book_get_static_capabilities): same.
+ (e_book_check_static_capability): same.
+ (startup_mainloop): new function, run bonobo_main.
+ (e_book_activate): start up a thread with startup_mainloop as the
+ start func.
+ (e_book_new): call e_book_activate.
+
+ * backend/idl/addressbook.idl: Add Book::open, remove the Book
+ from notifyBookOpened's args, and change BookFactory::openBook to
+ BookFactory::getBook.
+
+ * backend/pas/pas-backend-file.c (pas_backend_file_load_uri): add
+ only_if_exists - stop using the "create-initial" special file.
+
+ * backend/pas/pas-backend-vcf.c (pas_backend_vcf_load_uri): add
+ only_if_exists - stop using the "create-initial" special file.
+
+ * backend/pas/pas-backend.c (pas_backend_load_uri): add
+ @only_if_exists, and pass it along to the virtual method.
+ (pas_backend_open): new function, lock the mutex so only one
+ PASBook can actually call load_uri. call load_uri with
+ pas_book_get_uri, and req->only_if_exists.
+ (pas_backend_handle_request): rename process_client_request to
+ this, and expose it publicly. Also add a case statement for
+ "Open".
+ (real_add_client): gut this function, we don't need to create the
+ book anymore, just add the client to the list and do the weak
+ ref/ORBit small stuff.
+ (pas_backend_add_client): track change to signature - BookListener
+ -> PASBook.
+ (pas_backend_init): init open_mutex.
+ (pas_backend_dispose): free open_mutex.
+
+ * backend/pas/pas-backend.h (PASBackendClass): add @only_if_exists
+ to the load_uri virtual method, and change the add_client virtual
+ method to take a PASBook instead of a BookListener. add the same
+ args to _load_uri and add_client. Also, add prototypes for
+ pas_backend_handle_request and pas_backend_open.
+
+ * backend/pas/pas-book-factory.c
+ (_pas_book_factory_send_open_book_response): nuke.
+ (pas_book_factory_launch_backend): just return NULL, don't call
+ _pas_book_factory_send_open_book_response, in the error case.
+ (start_backend): nuke
+ (impl_GNOME_Evolution_Addressbook_BookFactory_getBook): rename
+ _openBook to this. clean up the code a bit. Create the PASBook
+ here, and always track change to pas_backend_add_client's type (we
+ pass the book now, not the listener).
+ (pas_book_factory_class_init): openBook -> getBook.
+
+ * backend/pas/pas-book.c
+ (impl_GNOME_Evolution_Addressbook_Book_open): new function, call
+ pas_backend_open.
+ (impl_GNOME_Evolution_Addressbook_Book_getVCard): get rid of the
+ signal crap, just call pas_backend_handle_request.
+ (impl_GNOME_Evolution_Addressbook_Book_getCardList): same.
+ (impl_GNOME_Evolution_Addressbook_Book_authenticateUser): same.
+ (impl_GNOME_Evolution_Addressbook_Book_addCard): same.
+ (impl_GNOME_Evolution_Addressbook_Book_removeCards): same.
+ (impl_GNOME_Evolution_Addressbook_Book_modifyCard): same.
+ (impl_GNOME_Evolution_Addressbook_Book_getChanges): same.
+ (impl_GNOME_Evolution_Addressbook_Book_getSupportedFields): same.
+ (impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods):
+ same.
+ (impl_GNOME_Evolution_Addressbook_Book_cancelOperation): same.
+ (pas_book_get_backend): aggregate some g_return_if_fail's.
+ (pas_book_get_listener): new function.
+ (pas_book_get_uri): new function.
+ (pas_book_respond_open): just call BookListener::notifyBookOpened.
+ (pas_book_construct): add @uri, and g_strdup it.
+ (pas_book_new): add @uri, and pass it to pas_book_construct.
+ (pas_book_class_init): remove the "request" signal stuff, and fill
+ in epv->open.
+
+ * backend/pas/pas-book.h: add PASOpenRequest struct/enum entry.
+ Also, add @uri to the pas_book_new args, and add a prototype for
+ pas_book_get_uri. Also, remove the "request" signal.
+
+2003-08-07 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book-factory.c
+ (pas_book_factory_get_n_backends): lock map_mutex around hash
+ table work.
+ (pas_book_factory_dump_active_backends): same.
+ (backend_last_client_gone_cb): same.
+ (_pas_book_factory_send_open_book_response): track CallStatus idl
+ change.
+ (start_backend): simplify this greatly, since the factory is
+ tagged with HINT_PER_THREAD.
+ (impl_GNOME_Evolution_Addressbook_BookFactory_openBook): lock
+ around hash table.
+ (pas_book_factory_init): initialize map_mutex.
+ (pas_book_factory_dispose): free map_mutex.
+
+2003-08-06 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-file.c
+ (pas_backend_file_book_view_copy): nuke.
+ (pas_backend_file_book_view_free): same.
+ (view_destroy): same.
+ (pas_backend_file_changes): #if notyet
+ (do_create): e-card -> e-contact.
+ (pas_backend_file_process_create_card): remove view handling from
+ here.
+ (pas_backend_file_process_remove_cards): same.
+ (pas_backend_file_process_modify_card): convert to e-contact, and
+ remove view handling.
+ (pas_backend_file_get_book_view): nuke.
+ (pas_backend_file_process_get_supported_fields): e-card-simple ->
+ e-contact.
+ (pas_backend_file_upgrade_db): e-card -> e-contact.
+ (pas_backend_file_cancel_operation): implement, just return
+ CouldNotCancel.
+ (pas_backend_file_class_init): assign cancel_operation, and remove
+ get_book_view assignment.
+ (pas_backend_file_init): remove book_views assignment.
+
+2003-08-06 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-vcf.c (pas_backend_vcf_book_view_copy):
+ nuke.
+ (pas_backend_vcf_book_view_free): same.
+ (view_destroy): same.
+ (insert_contact): new function, insert the contact into our hash
+ table.
+ (load_file): reimplement without the e_card stuff.
+ (foreach_build_list): e_card -> e_contact.
+ (save_file): mostly reimplement in terms of e-contact. more error
+ case work needs doing.
+ (do_create): e-card -> e-contact.
+ (pas_backend_vcf_process_create_card): remove the view handling
+ from here.
+ (pas_backend_vcf_process_remove_cards): implement this, just
+ remove it from the hash table and set ourselves to dirty.
+ (pas_backend_vcf_process_modify_card): remove the view handling
+ from here.
+ (pas_backend_vcf_process_get_book_view): nuke.
+ (pas_backend_vcf_process_get_supported_fields): reimplement in
+ terms of e-contact.
+ (INITIAL_VCARD): add in a FN attribute, and remove the quoted
+ printable encoding.
+ (pas_backend_vcf_cancel_operation): implement, just always return
+ CouldNotCancel.
+ (pas_backend_vcf_class_init): fill in cancel_operation, and remove
+ get_book_view_sync.
+ (pas_backend_vcf_init): remove book_views handling.
+
+ * backend/pas/pas-backend-vcf.h: update copyright.
+
+2003-08-06 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-sync.c (pas_backend_sync_remove_cards):
+ add out param @ids, so we can call pas_book_respond_remove
+ properly.
+ (_pas_backend_remove_cards): the other half of the change - pass
+ the ids on to pas_book_response_remove.
+ (pas_backend_sync_modify_card): add out param @old_vcard so we can
+ call pas_book_respond_modify properly.
+ (_pas_backend_modify_card): the other half of the change, pass the
+ old_vcard on to pas_book_respond_modify.
+ (pas_backend_sync_get_book_view): nuke.
+ (pas_backend_sync_get_changes): track change (book view -> GList)
+ (_pas_backend_is_threaded): nuke.
+ (_pas_backend_create_card): indent.
+ (_pas_backend_remove_cards): same.
+ (_pas_backend_modify_card): same.
+ (_pas_backend_get_card_list): same.
+ (_pas_backend_get_changes): same.
+ (_pas_backend_authenticate_user): same.
+ (_pas_backend_get_supported_fields): same.
+ (_pas_backend_get_supported_auth_methods): same.
+ (_pas_backend_get_book_view): nuke.
+ (pas_backend_sync_class_init): remove assignment to is_threaded
+ and get_book_view.
+
+ * backend/pas/pas-backend-sync.h: add out-params @ids to
+ remove_cards_sync, @old_vcard to modify_card_sync.
+ get_changes_sync's out-param is a GList instead of a book view,
+ and remove get_book_view_sync.
+
+ * backend/pas/pas-backend.c (pas_backend_get_book_view): nuke.
+ (pas_backend_is_threaded): nuke.
+ (pas_backend_start_threaded): nuke.
+ (pas_backend_init): initialize priv->views.
+ (pas_backend_dispose): free priv->views.
+ (pas_backend_get_book_views): new function, return priv->views.
+
+ * backend/pas/pas-backend.h: remove the get_book_view virtual
+ method, and the pas_backend_get_book_view prototype. Also, track
+ the CallStatus change, and add a cancel_operation virtual method
+ and prototype, and add pas_backend_get_book_views function, so the
+ PASBook's can get ahold of the list.
+
+ * backend/pas/pas-book-view.h: track collapsing of
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+
+ * backend/pas/pas-book-view.c: same.
+
+ * backend/pas/pas-card-cursor.[ch]: nuke
+
+ * backend/pas/pas-book.c: track collapsing of
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+ (impl_GNOME_Evolution_Addressbook_Book_getBookView): implement
+ this all here, instead of farming it out to the backends.
+ (impl_GNOME_Evolution_Addressbook_Book_getChanges): track change
+ to signature. this is no longer a book view, it'll return an
+ actual list.
+ (impl_GNOME_Evolution_Addressbook_Book_cancelOperation): new
+ function, implement.
+ (pas_book_respond_create): iterate over the views, notifying them
+ if the new card matches their query.
+ (pas_book_respond_remove): iterate over the views, telling them to
+ delete the card matching the id.
+ (pas_book_respond_modify): iterate over the views, notifying them
+ if they need to change/add/remove that card.
+ (view_destroy): move this here from the backends.
+ (pas_book_respond_get_book_view): weak-ref the book view.
+ (pas_book_new): remove the is_threaded switch on POA hints, and
+ always use PER_REQUEST.
+ (pas_book_class_init): fill in cancelOperation.
+
+ * backend/pas/pas-book.h: track collapsing of
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+
+2003-08-01 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-async.c: mostly finished.
+
+2003-08-01 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-async.[ch]: new files, create async methods
+ similar to the old ebook api that use GThread/GAsyncQueue to
+ simulate the old async behavior.
+
+2003-07-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/idl/addressbook.idl: collapse
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+
+2003-07-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-types.h: add EBookChangeType/EBookChange.
+
+2003-07-29 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book-view-listener.c: track collapsing of
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+
+ * backend/ebook/e-book-listener.c track collapsing of
+ Addressbook::BookListenerCallStatus and
+ Addressbook::BookView::CallStatus enums into
+ Addressbook::CallStatus.
+ (response_free): nuked
+ (e_book_listener_check_queue): nuked
+ (e_book_listener_queue_response): nuked
+ (e_book_listener_queue_progress): nuked
+ (e_book_listener_queue_get_view_response): nuked
+ (e_book_listener_queue_get_changes_response): nuked
+ (e_book_listener_queue_writable_status): nuked
+ (e_book_listener_queue_authentication_response): nuked
+ (e_book_listener_queue_get_supported_fields_response): nuked
+ (e_book_listener_queue_get_supported_auth_methods_response): nuked
+ (e_book_listener_dispose): nuked
+
+ * backend/ebook/e-book-listener.h: remove prototypes for
+ check_pending and pop_response.
+
+ * backend/ebook/e-book.c (e_book_get_changes): new function.
+ implement this as more of a getCardList type function, instead of
+ getBookView.
+ (e_book_response_get_changes): new function.
+ (e_book_free_change_list): new function.
+
+ * backend/ebook/e-book.h: add prototype for
+ e_book_free_change_list.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/ebook/e-book.c (e_book_get_book_view): new function,
+ implement this.
+ (e_book_response_get_book_view): same.
+ (e_book_get_contacts): remove the op so we don't see BUSY after
+ this request.
+ (e_book_handle_response): unifdef a few things.
+ (e_book_unload_uri): fix the assertion about URI_NOT_LOADED, and
+ unifdef some code.
+ (e_book_dispose): fix a typo.
+
+ * backend/ebook/e-book-view.c (e_book_view_handle_response):
+ rename _check_listener_queue to this. we don't need to pop the
+ response either, it's passed as an arg.
+ (e_book_view_construct): "response_queued" -> "response"
+ (e_book_view_start): new function, call BookView.start.
+ (e_book_view_dispose): track the signal id change.
+
+ * backend/ebook/e-book-view.h: add prototype for
+ e_book_view_start.
+
+ * backend/ebook/e-book-view-listener.c
+ (e_book_view_listener_check_queue): remove.
+ (e_book_view_listener_queue_response): just emit the signal.
+ (impl_BookViewListener_notify_card_added): spew.
+ (impl_BookViewListener_notify_card_changed): spew.
+ (impl_BookViewListener_notify_sequence_complete): spew.
+ (impl_BookViewListener_notify_progress): spew.
+ (e_book_view_listener_check_pending): remove
+ (e_book_view_listener_check_pop_response): remove
+ (e_book_view_listener_new): use the ALL_AT_IDLE poa policy.
+ (e_book_view_listener_init): remove the queue/timeout stuff.
+ (e_book_view_listener_dispose): remove the queue/timeout stuff.
+
+ * backend/ebook/e-book-view-listener.h: remove _check_pending and
+ _pop_response.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-backend-file.c (do_summary_query): remove the
+ completion_search argument, and remove the aggregating stuff.
+ just call pas_book_view_notify_add_1.
+ (pas_backend_file_book_view_copy): remove card_sexp crap.
+ (pas_backend_file_book_view_free): same.
+ (get_length): remove
+ (get_nth): remove
+ (cursor_destroy): remove
+ (vcard_matches_search): remove
+ (ecard_matches_search): remove
+ (pas_backend_file_search_timeout): remove the aggregating stuff.
+ just call pas_book_view_notify_add_1.
+ (pas_backend_file_search): simplify this a bunch.
+ (do_create): use pas_book_view_vcard_matches.
+ (pas_backend_file_process_get_card_list): add some more error
+ checks.
+ (pas_backend_file_process_get_book_view): unifdef this, and
+ implement it.
+ (pas_backend_file_start_book_view): kick off the search.
+ (pas_backend_file_get_uri): remove.
+ (pas_backend_file_class_init): remove get_uri, add
+ start_book_view.
+
+ * backend/pas/pas-backend-ldap.c (view_destroy): don't need to
+ unref the card_sexp, as the PASBookView owns it now.
+ (create_card_handler): use pas_book_view_vcard_matches.
+ (modify_card_modify_handler): same.
+ (ldap_get_view): initialize the view properly.
+ (pas_backend_ldap_get_uri): remove.
+ (pas_backend_ldap_class_init): remove the get_uri assignment.
+
+ * backend/pas/pas-backend-sync.c (_pas_backend_get_card_list):
+ don't free this, it's freed in the pas_book code.
+
+ * backend/pas/pas-backend-sync.h: make use of pas-types.h and
+ remove some typedefs.
+
+ * backend/pas/pas-backend-summary.h: same.
+
+ * backend/pas/pas-backend-card-sexp.h: same.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book.c
+ (impl_GNOME_Evolution_Addressbook_Book_getBookView): spew.
+ (pas_book_respond_create): unifdef this.
+ (pas_book_respond_remove): same.
+ (pas_book_respond_modify): same.
+ (pas_book_respond_authenticate_user): same.
+ (pas_book_respond_get_supported_fields): unref the iterator.
+ (pas_book_respond_get_book_view): unifdef, and add spew.
+
+ * backend/pas/pas-book.h: make use of pas-types.h and remove some
+ typedefs.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-types.h: new file, all the typedefs shared
+ between files here.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/pas-book-view.c (send_pending_adds): abstract all
+ the aggregating code to the book view. backends just call
+ notify_card_added and the superclass does all the aggregating.
+ (pas_book_view_notify_change): if there are pending adds, send
+ them before we send the change.
+ (pas_book_view_notify_remove): same.
+ (pas_book_view_notify_add): the other part of the aggregating
+ code.
+ (pas_book_view_notify_complete): send pending adds if there are
+ any.
+ (impl_GNOME_Evolution_Addressbook_BookView_start): new function,
+ call pas_backend_start_book_view.
+ (pas_book_view_get_card_query): new function.
+ (pas_book_view_get_card_sexp): new function.
+ (pas_book_view_get_backend): new function.
+
+ * backend/pas/pas-book-view.h: add a PASBackend arg to the
+ constructor, as well as the char* query and PASBackendCardSExp
+ form. also add accessors for card_query, card_sexp, and backend.
+
+ * backend/idl/addressbook.idl
+ (GNOME::Evolution::Addressbook::BookView): add start() method.
+ (GNOME::Evolution::Addressbook::BookListener): remove the oneway
+ tag from notifyBookOpened, notifyViewRequested, and
+ notifyChangesRequested so the call doesn't return until the remote
+ object has gotten the method call.
+
+ * backend/pas/pas-backend.c (pas_backend_load_uri): fill in the
+ uri slot if the load was successful.
+ (pas_backend_get_uri): return the uri, remove the virtual method
+ call.
+ (pas_backend_start_book_view): new function.
+ (process_client_request): ifdef out the threaded foo, since i'm
+ not certain it's at all necessary.
+ (real_add_client): remove the bonobo_object_unref of the book,
+ since it's immortal.
+ (pas_backend_dispose): free the uri.
+
+ * backend/pas/pas-backend.h: remove the get_uri virtual method,
+ and add the start_book_view virtual method and
+ pas_backend_start_book_view prototype.
+
+2003-07-23 Chris Toshok <toshok@ximian.com>
+
+ * backend/pas/Makefile.am (libpasvcf_a_SOURCES): new.
+ (noinst_LIBRARIES): add libpasvcf.a
+
+ * backend/pas/pas-backend-vcf.[ch]: new files, implement a vcard
+ file backend. the backend api still needs a little work, but it's
+ getting easier to write backends.
+
2003-07-23 Chris Toshok <toshok@ximian.com>
* printing/e-contact-print.c (e_contact_print_response): deal with
diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am
index d0d48e5076..7bbbce2434 100644
--- a/addressbook/Makefile.am
+++ b/addressbook/Makefile.am
@@ -3,7 +3,9 @@ CONDUIT_SUBDIR=conduit
endif
SUBDIRS = \
- backend printing gui tools $(CONDUIT_SUBDIR)
+ backend util printing gui $(CONDUIT_SUBDIR)
EXTRA_DIST = \
ChangeLog.pre-1-4
+
+# XXX tools \ No newline at end of file
diff --git a/addressbook/backend/ebook/.cvsignore b/addressbook/backend/ebook/.cvsignore
index e3e9c805bb..17250008f8 100644
--- a/addressbook/backend/ebook/.cvsignore
+++ b/addressbook/backend/ebook/.cvsignore
@@ -12,6 +12,7 @@ addressbook.h
test-card
test-client
test-client-list
+test-ebook
load-pine-addressbook
load-gnomecard-addressbook
evolution-vcard-importer
diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am
index 9d2b6d1b05..e83e3e1411 100644
--- a/addressbook/backend/ebook/Makefile.am
+++ b/addressbook/backend/ebook/Makefile.am
@@ -1,16 +1,7 @@
-noinst_PROGRAMS = test-card test-client test-client-list
-
-privlibexec_PROGRAMS = \
- evolution-vcard-importer \
- evolution-ldif-importer
-
-toolsdir = $(privlibexecdir)/
-tools_PROGRAMS = \
- load-pine-addressbook \
- load-gnomecard-addressbook
-
# CORBA stuff
+SUBDIRS = . tests
+
CORBA_ADDRESSBOOK_SOURCE_H = \
addressbook.h
CORBA_ADDRESSBOOK_SOURCE_C = \
@@ -38,13 +29,10 @@ INCLUDES = \
-DLIBDIR=\"$(libdir)\" \
-DG_LOG_DOMAIN=\"EBook\" \
-I$(top_srcdir) \
- -I$(top_srcdir)/camel \
-I$(top_srcdir)/addressbook/backend \
-I$(top_srcdir)/addressbook/ename \
-I$(top_builddir)/addressbook/backend \
-I$(top_builddir)/addressbook/ename \
- -I$(top_builddir)/shell \
- -I$(top_srcdir)/shell \
-DG_DISABLE_DEPRECATED \
-DLIBGNOME_DISABLE_DEPRECATED \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@ -53,113 +41,39 @@ privlib_LTLIBRARIES = libebook.la
libebook_la_SOURCES = \
$(CORBA_SOURCE) \
- e-book-listener.c \
+ addressbook.h \
e-book-marshal.c \
+ e-book-query.c \
e-book-view-listener.c \
e-book-view.c \
+ e-book-listener.c \
e-book.c \
- e-book-util.c \
- e-card-cursor.c \
- e-card-simple.c \
- e-card.c \
- e-card-compare.c \
- e-destination.c
+ e-book-async.c \
+ e-contact.c \
+ e-vcard.c
libebook_la_LIBADD = \
$(top_builddir)/libversit/libversit.la \
- $(top_builddir)/camel/libcamel.la \
$(top_builddir)/e-util/ename/libename.la \
$(top_builddir)/e-util/libeutil.la
libebookincludedir = $(privincludedir)/ebook
libebookinclude_HEADERS = \
- e-book-listener.h \
- e-book-types.h \
+ e-book-query.h \
e-book-view-listener.h \
e-book-view.h \
+ e-book-types.h \
+ e-book-listener.h \
e-book.h \
- e-book-util.h \
- e-card-cursor.h \
- e-card-simple.h \
- e-card-types.h \
- e-card.h \
- e-card-compare.h \
- e-destination.h \
- addressbook.h
-
+ e-contact.h \
+ e-vcard.h
MARSHAL_GENERATED = e-book-marshal.c e-book-marshal.h
@EVO_MARSHAL_RULE@
-test_client_SOURCES = \
- test-client.c
-
-test_client_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-test_client_list_SOURCES = \
- test-client-list.c
-
-test_client_list_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-test_card_SOURCES = \
- test-card.c
-
-test_card_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-evolution_vcard_importer_SOURCES = \
- evolution-vcard-importer.c
-
-evolution_vcard_importer_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/shell/importer/libevolution-importer.la \
- $(DB3_LDADD)
-
-evolution_ldif_importer_SOURCES = \
- evolution-ldif-importer.c
-
-evolution_ldif_importer_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/shell/importer/libevolution-importer.la \
- $(DB3_LDADD)
-
-load_pine_addressbook_SOURCES = \
- load-pine-addressbook.c
-
-load_pine_addressbook_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-load_gnomecard_addressbook_SOURCES = \
- load-gnomecard-addressbook.c
-
-load_gnomecard_addressbook_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-
-BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED) $(server_DATA)
+BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
-
-server_in_files = GNOME_Evolution_Addressbook_VCard_Importer.server.in.in \
- GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in
-
-server_DATA = $(server_in_files:.server.in.in=.server)
-%.server.in: %.server.in.in
- sed -e "s|\@LIBEXECDIR\@|$(privlibexecdir)|" $< > $@
-
-
-@INTLTOOL_SERVER_RULE@
-
-EXTRA_DIST = $(server_in_files) $(server_DATA) e-book-marshal.list
diff --git a/addressbook/backend/ebook/docs/rfc2739.txt b/addressbook/backend/ebook/docs/rfc2739.txt
new file mode 100644
index 0000000000..5c1dbbcf77
--- /dev/null
+++ b/addressbook/backend/ebook/docs/rfc2739.txt
@@ -0,0 +1,899 @@
+
+
+
+
+
+
+Network Working Group T. Small
+Request for Comments: 2739 XpertSite.Com
+Category: Standards Track D. Hennessy
+ ISOCOR
+ F. Dawson
+ Lotus
+ January 2000
+
+
+ Calendar Attributes for vCard and LDAP
+
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ When scheduling a calendar entity, such as an event, it is a
+ prerequisite that an organizer has the calendar address of each
+ attendee that will be invited to the event. Additionally, access to
+ an attendee's current "busy time" provides an a priori indication of
+ whether the attendee will be free to participate in the event.
+
+ In order to meet these challenges, a calendar user agent (CUA) needs
+ a mechanism to locate (URI) individual user's calendar and free/busy
+ time.
+
+ This memo defines three mechanisms for obtaining a URI to a user's
+ calendar and free/busy time. These include:
+
+ - Manual transfer of the information;
+
+ - Personal data exchange using the vCard format; and
+
+ - Directory lookup using the LDAP protocol.
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 1]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+Table of Contents
+
+ 1 CALENDARING AND SCHEDULING URIS...................................3
+ 1.1 FREE/BUSY URI (FBURL) .........................................3
+ 1.2 CALENDAR ACCESS URI (CAPURI) ..................................4
+ 1.3 CALENDAR URI (CALURI) .........................................4
+ 1.4 DEFAULT URIS ..................................................4
+ 2 DISTRIBUTION......................................................4
+ 2.1 MANUAL TRANSFER ...............................................5
+ 2.2 PERSONAL DATA EXCHANGE USING A VCARD ..........................5
+ 2.3 VCARD SCHEMA EXTENSIONS .......................................5
+ 2.3.1 FBURL Property IANA Registration ...........................6
+ 2.3.2 CALADRURI Property IANA Registration .......................7
+ 2.3.3 CAPURI Property IANA Registration ......................... 8
+ 2.3.4 CALURI Property IANA Registration ......................... 8
+ 2.4 DIRECTORY LOOKUP USING THE LDAP V3 PROTOCOL .................. 9
+ 2.4.1 LDAP Schema Extensions .................................... 9
+ 2.4.2 Notation ..................................................10
+ 2.4.3 Object Definitions ........................................10
+ 2.4.3.1 calEntry ..............................................10
+ 2.4.4 Attribute Definitions .....................................10
+ 2.4.4.1 calCalURI .............................................10
+ 2.4.4.2 calFBURL ..............................................10
+ 2.4.4.3 calCAPURI .............................................11
+ 2.4.4.4 calCalAdrURI ..........................................11
+ 2.4.4.5 calOtherCalURIs .......................................11
+ 2.4.4.6 calOtherFBURLs ........................................11
+ 2.4.4.7 calOtherCAPURIs .......................................12
+ 2.4.4.8 calOtherCalAdrURIs ....................................12
+ 3 IANA Considerations..............................................12
+ 4 Security Considerations..........................................12
+ 5 Acknowledgments..................................................13
+ 6 Authors' Addresses...............................................13
+ 7 Bibliography.....................................................15
+ 8 Full Copyright Statement.........................................16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 2]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+1 Calendaring and Scheduling URIs
+
+ This memo defines four classes of URIs. URIs are more useful if it is
+ understood what the URIs point to. Here is a brief description:
+
+1.1 Free/Busy URI (FBURL)
+
+ The free/busy URI is defined to be a transport independent location
+ where a client can obtain information about when a user is busy. At
+ the present time, this URI only points to busy time data. Future
+ revisions of this specification may provide for the extended
+ capability of publishing free time data.
+
+ If a calendaring and scheduling client (i.e., CUA) were to retrieve
+ data from this location using FTP or HTTP, it would get back an
+ iCalendar object [4] containing one or more "VFREEBUSY" calendar
+ components. If a MIME transport is being used, the response will be
+ contained within a "text/calendar" MIME body part as specified in the
+ iCalendar specification [4]. For example:
+
+ BEGIN:VCALENDAR
+ VERSION:2.0
+ PRODID:-//hacksw/handcal//NONSGML v1.0//EN
+ METHOD:PUBLISH
+ BEGIN:VFREEBUSY
+ ATTENDEE:MAILTO:jane_doe@host1.com
+ DTSTART:19971013T050000Z
+ DTEND:19971124T050000Z
+ DTSTAMP:19970901T083000Z
+ FREEBUSY:19971015T133000Z/19971015T180000Z
+ FREEBUSY:19971015T190000Z/19971015T220000Z
+ FBURL:http://www.host.com/calendar/busy/jdoe.ifb
+ END:VFREEBUSY
+ END:VCALENDAR
+
+ The amount of busy time data pointed to by the FBURL will generally
+ be pre-determined; for example one month of busy time data. As a
+ guideline, it is recommended that the previous six weeks of busy time
+ data be published at the location associated with the FBURL. If this
+ URI points to a file resource, it is recommended that the file
+ extension be "ifb" to distinguish it from an arbitrary iCalendar
+ object (e.g., with the "ics" file extension).
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 3]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+1.2 Calendar Access URI (CAPURI)
+
+ The Calendar Access URI is defined to be a protocol independent
+ location from which a calendaring and scheduling client (i.e., CUA)
+ can communicate with a user's entire calendar.
+
+ The semantics for using this URI as an access protocol locator are
+ yet to be defined by the IETF CALSCH Working Group. This will be
+ addressed in the "Calendar Access Protocol" specification.
+
+1.3 Calendar URI (CALURI)
+
+ The Calendar URI is defined to be a protocol independent location
+ from which a calendaring and scheduling client (i.e. CUA) can
+ retrieve an entire copy of a user's calendar. Retrieving data from
+ this URI obtains a published "snapshot" of the user's calendar.
+
+ HTTP URI -- If the URI is an HTTP URI, then the content returned with
+ a GET should be a "text/calendar" MIME body part containing one or
+ more iCalendar object.
+
+ FTP URI -- If the URI is an FTP URI, then the resource pointed to
+ should be a file with an "ics" file extension containing one or more
+ iCalendar objects.
+
+1.4 Default URIs
+
+ There are many cases where a user may have more than one calendar. In
+ these cases, a user may have multiple URIs, each URI pointing to a
+ calendar or free/busy data.
+
+ To make the case of multiple calendars simpler for clients, the
+ concept of the "default" calendar is introduced. A "default" calendar
+ is one that the user has designated as the calendar that other users
+ should look at when accessing the user's calendar, or retrieving the
+ user's free/busy time.
+
+ The default calendar may, in fact, include rolled-up information from
+ all the user's other calendars. The other calendars may only exist
+ for organizational purposes.
+
+2 Distribution
+
+ These four URIs provide valuable pointers to calendaring and
+ scheduling data that other users need in order to know when to
+ schedule meetings, etc. There are several possibilities on how users
+ can communicate these URIs to other users. The following section
+ outlines how these URIs can be distributed to other users.
+
+
+
+Small, et al. Standards Track [Page 4]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+2.1 Manual Transfer
+
+ The simplest way to obtain these URIs is for a user to communicate
+ the URIs using some out-of-band mechanism such as verbally, or in an
+ e-mail message, or by printing these URIs on a paper business card.
+
+ When using this mechanism, the user obtains these URIs using an out-
+ of-band mechanism and then enters these URIs into their calendaring
+ software manually.
+
+2.2 Personal Data Exchange Using A vCard
+
+ A more sophisticated way to obtain these URIs is for users to publish
+ vCards containing these URIs. The vCard object can be transferred
+ between one another. Since many e-mail clients allow a user to
+ automatically include a vCard with every message that the user sends,
+ this provides a simple, transparent way for a user to distribute
+ their calendaring and scheduling URIs.
+
+ On the receiving end, an e-mail client that provides an integrated
+ vCard database can provide a way to lookup calendaring URIs for users
+ whose vCards are stored locally.
+
+2.3 vCard Schema Extensions
+
+ Since the vCard [3] specification doesn't specify how to encode
+ calendaring URIs in a vCard, this section is provided as an extension
+ to vCard which specifies how to encode calendaring URIs within a
+ vCard.
+
+ Inside a vCard object, four new properties are defined: "CALURI",
+ "CAPURI", "CALADRURI", and "FBURL", as defined above.
+
+ Any vCard can have one or more of these properties, each representing
+ a calendar or free/busy time that is associated with the user.
+
+ One of these properties can be designated as the "default" by adding
+ the "PREF" parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 5]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ Here is a simple example of a vCard containing a "FBURL" and a
+ "CALURI".
+
+ BEGIN:VCARD
+ VERSION:3.0
+ N:Dun;Alec
+ FN:Alec Dun
+ ORG:Microsoft Corporation
+ ADR;WORK;POSTAL;PARCEL:;;One Microsoft Way;
+ Redmond;WA;98052-6399;USA
+ TEL;WORK;MSG:+1-206-936-4544
+ TEL;WORK;FAX:+1-206-936-7329
+ EMAIL;INTERNET:user@host1.com
+ CALADRURI;PREF:mailto:user@host1.com
+ CALURI;PREF:http://cal.host1.com/user/cal.ics
+ FBURL;PREF:http://cal.host1.com/user/fb.ifb
+ CALURI:http://cal.company.com/projectA/pjtA.ics
+ FBURL:http://cal.company.com/projectA/pjtAfb.ifb
+ END:VCARD
+
+2.3.1 FBURL Property IANA Registration
+
+ To: ietf-mime-directory@imc.org
+
+ Subject: Registration of FBURL type for text/directory MIME type
+ vCard profile.
+
+ Type name: FBURL
+
+ Type purpose: To specify the URI for a user's busy time in a vCard
+ object.
+
+ Type encoding: 8bit
+
+ Type value: A single URI value.
+
+ Type special notes: Where multiple FBURL properties are specified,
+ the default FBURL property is indicated with the PREF parameter. The
+ FTP or HTTP type of URI points to an iCalendar object associated with
+ a snapshot of the last six weeks of the user's busy time data. If the
+ iCalendar object is represented as a file or document, it's file type
+ should be "ifb".
+
+ Intended usage: Refer to section 1.1.
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 6]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ Type examples:
+
+ FBURL;PREF:http://www.host1.com/busy/janedoe
+ FBURL:FTP://ftp.host.com/busy/project-a.ifb
+
+2.3.2 CALADRURI Property IANA Registration
+
+ To: ietf-mime-directory@imc.org
+
+ Subject: Registration of CALADRURI type for application/directory
+ MIME type vCard profile.
+
+ Type name: CALADRURI
+
+ Type purpose: To specify the location to which an event request
+ should be sent for the user.
+
+ Type encoding: 8bit
+
+ Type value: A single URI value.
+
+ Type special notes: Where multiple CALADRURI properties are
+ specified, the default CALADRURI property is indicated with the PREF
+ parameter.
+
+ Intended usage: Refer to section 1.2.
+
+ Type examples:
+
+ CALADRURI;PREF:mailto:janedoe@host.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 7]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+2.3.3 CAPURI Property IANA Registration
+
+ To: ietf-mime-directory@imc.org
+
+ Subject: Registration of CAPURI type for application/directory MIME
+ type vCard profile.
+
+ Type name: CAPURI
+
+ Type purpose: To specify a protocol independent location from which a
+ calendaring and scheduling client (i.e., CUA) can communicate with a
+ user's entire calendar.
+
+ Type encoding: 8bit
+
+ Type value: A single URI value.
+
+ Type special notes: Where multiple CAPURI properties are specified,
+ the default CAPURI property is indicated with the PREF parameter.
+
+ Intended usage: Refer to section 1.3.
+
+2.3.4 CALURI Property IANA Registration
+
+ To: ietf-mime-directory@imc.org
+
+ Subject: Registration of CALURI type for text/directory MIME type
+ vCard profile.
+
+ Type name: CALURI
+
+ Type purpose: To specify the URI for a user's calendar in a vCard
+ object.
+
+ Type encoding: 8bit
+
+ Type value type: A single URI value.
+
+ Type special notes: Where multiple CALURI properties are specified,
+ the default CALURI property is indicated with the PREF parameter. The
+ property should contain a URI pointing to an iCalendar object
+ associated with a snapshot of the user's calendar store. If the
+ iCalendar object is represented as a file or document, it's file type
+ should be "ics".
+
+ Intended usage: Refer to section 1.4.
+
+
+
+
+
+Small, et al. Standards Track [Page 8]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ Type examples:
+
+ CALURI;PREF:http://cal.host1.com/calA
+ CALURI:ftp://ftp.host1.com/calA.ics
+
+2.4 Directory Lookup Using The LDAP v3 Protocol
+
+ Another way to obtain these URIs is to look them up in a directory
+ using the LDAP protocol [1].
+
+ If a user's URIs can be found using directory lookup (i.e., searching
+ for one of the LDAP schema extensions defined below), they should, in
+ general, be considered "more up-to-date" than URIs in any vCards that
+ are stored locally.
+
+2.4.1 LDAP Schema Extensions
+
+ In order to encode the calendaring URIs in the directory, the
+ following are defined:
+
+ - One object class:
+
+ - calEntry
+
+ - Eight attributes:
+
+ - calCalURI
+
+ - calFBURL
+
+ - calCAPURI
+
+ - calCalAdrURI
+
+ - calOtherCalURIs
+
+ - calOtherFBURLs
+
+ - calOtherCAPURIs
+
+ - calOtherCalAdrURIs
+
+ The calCalURI contains the URI to a snapshot of the user's entire
+ default calendar. The calFBURL contains the URI to the user's default
+ busy time data. The calCAPURI represents contains a URI that can be
+ used to communicate with the user's calendar. The calCalAdrURI
+ contains a URI that points to the location to which event requests
+ should be sent for that user.
+
+
+
+Small, et al. Standards Track [Page 9]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ The calOtherCalURIs is a multi-valued property containing URIs to
+ snapshots of other calendars that the user may have. The
+ calOtherFBURLs is a multi-valued property containing URIs to other
+ free/busy data that the user may have. The calOtherCAPURIs attribute
+ is a multi-valued property containing URIs to other calendars that
+ the user may have. The calOtherCalAdrURIs attribute is a multi-valued
+ property containing URIs to other locations that a user may want
+ event requests sent to.
+
+ There is no predetermined order to the values in either multi-valued
+ property.
+
+2.4.2 Notation
+
+ The notation used in this memo is the same as that used in [2].
+
+2.4.3 Object Definitions
+
+2.4.3.1 calEntry
+
+ The Calendar Entry is a class derived from "TOP" [2], which contains
+ the four calendaring attributes.
+
+ (1.2.840.113556.1.5.87
+ NAME 'calEntry'
+ TOP
+ AUXILIARY
+ MAY (calCalURI calFBURL calOtherCalURIs calOtherFBURLs calCAPURI
+ calOtherCAPURLs)
+ )
+
+2.4.4 Attribute Definitions
+
+2.4.4.1 calCalURI
+
+ (1.2.840.113556.1.4.478
+ NAME 'calCalURI'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ USAGE userApplications
+ )
+
+2.4.4.2 calFBURL
+
+ (1.2.840.113556.1.4.479
+ NAME 'calFBURL'
+ EQUALITY caseIgnoreMatch
+
+
+
+Small, et al. Standards Track [Page 10]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ USAGE userApplications
+ )
+
+2.4.4.3 calCAPURI
+
+ (1.2.840.113556.1.4.480
+ NAME 'calCAPURI'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ USAGE userApplications
+ )
+
+2.4.4.4 calCalAdrURI
+
+ (1.2.840.113556.1.4.481
+ NAME 'calCalAdrURI'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ USAGE userApplications
+ )
+
+2.4.4.5 calOtherCalURIs
+
+ (1.2.840.113556.1.4.482
+ NAME 'calOtherCalURIs'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ MULTI-VALUE
+ USAGE userApplications
+ )
+
+2.4.4.6 calOtherFBURLs
+
+ (1.2.840.113556.1.4.483
+ NAME 'calOtherFBURLs'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ MULTI-VALUE
+ USAGE userApplications
+ )
+
+
+
+
+
+Small, et al. Standards Track [Page 11]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+2.4.4.7 calOtherCAPURIs
+
+ (1.2.840.113556.1.4.484
+ NAME 'calOtherCAPURIs'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ MULTI-VALUE
+ USAGE userApplications
+ )
+
+2.4.4.8 calOtherCalAdrURIs
+
+ (1.2.840.113556.1.4.485
+ NAME 'calOtherCalAdrURIs'
+ EQUALITY caseIgnoreMatch
+ SUBSTRING caseIgnoreMatch
+ SYNTAX 'IA5String'
+ MULTI-VALUE
+ USAGE userApplications
+ )
+
+3 IANA Considerations
+
+ This memo defines IANA registered extensions to the attributes
+ defined by LDAP [1] and vCard [3].
+
+ IANA registration proposals for vCard are to be emailed to the
+ registration agent for the "text/directory" MIME content-type,
+ <MAILTO: ietf-mime-directory@imc.org> using the format defined in
+ [3].
+
+4 Security Considerations
+
+ Standard vCard and LDAP security rules and support apply for the
+ extensions described in this document, and there are no special
+ security issues for these extensions.
+
+ Please note, though, that LDAP servers may permit anonymous clients
+ to refresh entries which they did not create. Servers are also
+ permitted to control a refresh access to an entry by requiring
+ clients to bind before issuing a RefreshRequest. This will have
+ implications on the server performance and scalability.
+
+ Please also note, though, that vCard objects may have been created by
+ an entity other than that represented by the vCard. Recipients should
+ be certain of the source that generated the vCard.
+
+
+
+
+Small, et al. Standards Track [Page 12]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ Also, care should be taken in making use of information obtained from
+ directory servers that has been supplied by client, as it may now be
+ out of date. In many networks, for example, IP addresses are
+ automatically assigned when a host connects to the network, and may
+ be reassigned if that host later disconnects. An IP address obtained
+ from the directory may no longer be assigned to the host that placed
+ the address in the directory. This issue is not specific to LDAP or
+ dynamic directories.
+
+5 Acknowledgments
+
+ The authors wish to acknowledge the work of Alec Dun, who acted as an
+ author for the early drafts of this memo. In addition, this document
+ received input from the various participants in the IETF CALSCH
+ Working Group discussions.
+
+6 Authors' Addresses
+
+ The following address information is provided in a vCard v3.0 [3],
+ Electronic Business Card, format.
+
+ BEGIN:VCARD
+ VERSION:3.0
+ N:Small;Tony
+ FN:Tony Small
+ ORG:XpertSite.Com
+ ADR;TYPE=WORK,POSTAL,PARCEL:;;4700 42nd Ave. SW, Suite 440;
+ Seattle;WA;98116;USA
+ TEL;TYPE=WORK,MSG:+1-206-937-9972
+ TEL;TYPE=WORK,FAX:+1-206-936-7329
+ EMAIL;TYPE=INTERNET:tony@xpertsite.com
+ CALADRURI:MAILTO:tony@xpertsite.com
+ END:VCARD
+
+ BEGIN:VCARD
+ VERSION:3.0
+ N:Hennessy;Denis
+ FN:Denis Hennessy
+ ORG:ISOCOR
+ ADR;TYPE=WORK,POSTAL,PARCEL:;;42-47 Lower Mount St;
+ Dublin 2;Ireland
+ TEL;TYPE=WORK,MSG:+353-1-676-0366
+ TEL;TYPE=WORK,FAX:+353-1-676-0856
+ EMAIL;TYPE=INTERNET:denis.hennessy@isocor.com
+ CALADRURI:MAILTO:denis.hennessy@isocor.com
+ END:VCARD
+
+
+
+
+
+Small, et al. Standards Track [Page 13]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+ BEGIN:VCARD
+ VERSION:3.0
+ N:Dawson;Frank
+ FN:Frank Dawson
+ ORG:Lotus Development Corporation
+ ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive;
+ Raleigh;NC;27613-3502;USA
+ TEL;TYPE=WORK,PREF:+1-617-693-8728
+ TEL;TYPE=WORK,MSG:+1-919-676-9515
+ TEL;TYPE=FAX:+1-617-693-8728
+ EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com
+ EMAIL;TYPE=INTERNET:fdawson@earthlink.net
+ CALADRURI;TYPE=PREF:MAILTO:Frank_Dawson@Lotus.com
+ CALADRURI:MAILTO:fdawson@earthlink.net
+ URL:http://home.earthlink.net/~fdawson
+ END:VCARD
+
+ This memo is a result of the work of the Internet Engineering Task
+ Force Calendaring and scheduling Working Group. The chairman of that
+ working group is:
+
+ BEGIN:VCARD
+ VERSION:3.0
+ N:Egen;Pat
+ FN:Pat Egen
+ ORG:Engan Consulting
+ ADR;TYPE=WORK:;;803 Creek Overlook;Chattanooga;TN;37415;USA
+ TEL;TYPE=WORK,VOICE:423.875.2652
+ TEL;TYPE=WORK,FAX:423.875.2017
+ EMAIL:pregen@egenconsulting.com
+ URL:http://www.egenconsulting.com
+ CALADRURI:MAILTO:pregen@egenconsulting.com
+ END:VCARD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 14]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+7 Bibliography
+
+ [1] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access
+ Protocol (v3)", RFC 2251, December 1997.
+
+ [2] Wahl, M., Coulbeck, A., Howes, T. and S. Kille, "Lightweight
+ Directory Access Protocol (v3): Attribute Syntax Definitions",
+ RFC 2252, December 1997.
+
+ [3] Dawson, F. and T. Howes, "vCard MIME Directory Profile", RFC
+ 2426, September 1998.
+
+ [4] Dawson, F. and D. Stenerson, "Internet Calendaring and Scheduling
+ Core Object Specification (iCalendar)", RFC 2445, November 1997.
+
+ [5] Dawson, F. and S. Mansour, "iCalendar Message-Based
+ Interopability Protocal (iMIP)", RFC 2447, November 1997.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 15]
+
+RFC 2739 Locating a Calendar User January 2000
+
+
+8 Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Small, et al. Standards Track [Page 16]
+
diff --git a/addressbook/backend/ebook/e-book-async.c b/addressbook/backend/ebook/e-book-async.c
new file mode 100644
index 0000000000..2ccc565eb9
--- /dev/null
+++ b/addressbook/backend/ebook/e-book-async.c
@@ -0,0 +1,1120 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include "ebook/e-book-async.h"
+
+static GThread *worker_thread;
+static GAsyncQueue *to_worker_queue;
+static GAsyncQueue *from_worker_queue;
+
+typedef struct _EBookMsg EBookMsg;
+
+typedef void (*EBookMsgHandler)(EBookMsg* msg);
+typedef void (*EBookMsgDtor)(EBookMsg* msg);
+
+struct _EBookMsg {
+ EBookMsgHandler handler;
+ EBookMsgDtor dtor;
+};
+
+static gpointer
+worker (gpointer data)
+{
+ while (TRUE) {
+ EBookMsg *msg = g_async_queue_pop (to_worker_queue);
+ msg->handler (msg);
+ msg->dtor (msg);
+ }
+
+ return NULL;
+}
+
+static gboolean
+main_thread_check_for_response (gpointer data)
+{
+ EBookMsg *msg;
+
+ while ((msg = g_async_queue_try_pop (from_worker_queue)) != NULL) {
+ msg->handler (msg);
+ msg->dtor (msg);
+ }
+
+ return TRUE;
+}
+
+static void
+e_book_msg_init (EBookMsg *msg, EBookMsgHandler handler, EBookMsgDtor dtor)
+{
+ msg->handler = handler;
+ msg->dtor = dtor;
+}
+
+static void
+init_async()
+{
+ static gboolean init_done = FALSE;
+ if (!init_done) {
+ init_done = TRUE;
+ to_worker_queue = g_async_queue_new ();
+ from_worker_queue = g_async_queue_new ();
+ worker_thread = g_thread_create (worker, NULL, FALSE, NULL);
+ g_timeout_add (300, main_thread_check_for_response, NULL);
+ }
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ char *uri;
+ EBookCallback open_response;
+ gpointer closure;
+} LoadUriMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookCallback open_response;
+ gpointer closure;
+} LoadUriResponse;
+
+static void
+_load_uri_response_handler (EBookMsg *msg)
+{
+ LoadUriResponse *resp = (LoadUriResponse*)msg;
+
+ resp->open_response (resp->book, resp->status, resp->closure);
+}
+
+static void
+_load_uri_response_dtor (EBookMsg *msg)
+{
+ LoadUriResponse *resp = (LoadUriResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_load_uri_handler (EBookMsg *msg)
+{
+ LoadUriMsg *uri_msg = (LoadUriMsg *)msg;
+ LoadUriResponse *response;
+ GError *error = NULL;
+
+ response = g_new (LoadUriResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _load_uri_response_handler, _load_uri_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_load_uri (uri_msg->book, uri_msg->uri, FALSE, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+
+ response->book = uri_msg->book;
+ response->open_response = uri_msg->open_response;
+ response->closure = uri_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_load_uri_dtor (EBookMsg *msg)
+{
+ LoadUriMsg *uri_msg = (LoadUriMsg *)msg;
+
+ g_free (uri_msg->uri);
+ g_free (uri_msg);
+}
+
+void
+e_book_async_load_uri (EBook *book,
+ const char *uri,
+ EBookCallback open_response,
+ gpointer closure)
+{
+ LoadUriMsg *msg;
+
+ init_async ();
+
+ msg = g_new (LoadUriMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _load_uri_handler, _load_uri_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->uri = g_strdup (uri);
+ msg->open_response = open_response;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+}
+
+
+void
+e_book_async_unload_uri (EBook *book)
+{
+ e_book_unload_uri (book, NULL);
+}
+
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBookCallback open_response;
+ gpointer closure;
+} DefaultBookMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookCallback open_response;
+ gpointer closure;
+} DefaultBookResponse;
+
+static void
+_default_book_response_handler (EBookMsg *msg)
+{
+ LoadUriResponse *resp = (LoadUriResponse*)msg;
+
+ resp->open_response (resp->book, resp->status, resp->closure);
+}
+
+static void
+_default_book_response_dtor (EBookMsg *msg)
+{
+ LoadUriResponse *resp = (LoadUriResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_default_book_handler (EBookMsg *msg)
+{
+ DefaultBookMsg *dfb_msg = (DefaultBookMsg *)msg;
+ DefaultBookResponse *response;
+ GError *error = NULL;
+
+ response = g_new (DefaultBookResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _default_book_response_handler, _default_book_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_default_addressbook (&response->book, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+
+ response->open_response = dfb_msg->open_response;
+ response->closure = dfb_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_default_book_dtor (EBookMsg *msg)
+{
+ DefaultBookMsg *dfb_msg = (DefaultBookMsg *)msg;
+
+ g_free (dfb_msg);
+}
+
+void
+e_book_async_get_default_addressbook (EBookCallback open_response,
+ gpointer closure)
+{
+ DefaultBookMsg *msg;
+
+ init_async ();
+
+ msg = g_new (DefaultBookMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _default_book_handler, _default_book_dtor);
+
+ msg->open_response = open_response;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookFieldsCallback cb;
+ gpointer closure;
+} GetFieldsMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ GList *fields;
+ EBookFieldsCallback cb;
+ gpointer closure;
+} GetFieldsResponse;
+
+static void
+_get_fields_response_handler (EBookMsg *msg)
+{
+ GetFieldsResponse *resp = (GetFieldsResponse*)msg;
+ GList *l;
+ EList *fields = e_list_new ((EListCopyFunc) g_strdup,
+ (EListFreeFunc) g_free,
+ NULL);
+
+ for (l = resp->fields; l; l = l->next)
+ e_list_append (fields, l->data);
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, fields, resp->closure);
+
+ g_object_unref (fields);
+}
+
+static void
+_get_fields_response_dtor (EBookMsg *msg)
+{
+ GetFieldsResponse *resp = (GetFieldsResponse*)msg;
+
+ g_list_foreach (resp->fields, (GFunc)g_free, NULL);
+ g_list_free (resp->fields);
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_get_fields_handler (EBookMsg *msg)
+{
+ GetFieldsMsg *fields_msg = (GetFieldsMsg *)msg;
+ GetFieldsResponse *response;
+ GError *error = NULL;
+
+ response = g_new (GetFieldsResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _get_fields_response_handler, _get_fields_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_supported_fields (fields_msg->book, &response->fields, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = fields_msg->book;
+ response->cb = fields_msg->cb;
+ response->closure = fields_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+guint
+e_book_async_get_supported_fields (EBook *book,
+ EBookFieldsCallback cb,
+ gpointer closure)
+{
+ GetFieldsMsg *msg;
+
+ init_async ();
+
+ msg = g_new (GetFieldsMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _get_fields_handler, (EBookMsgDtor)g_free);
+
+ msg->book = g_object_ref (book);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookAuthMethodsCallback cb;
+ gpointer closure;
+} GetMethodsMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ GList *methods;
+ EBookAuthMethodsCallback cb;
+ gpointer closure;
+} GetMethodsResponse;
+
+static void
+_get_methods_response_handler (EBookMsg *msg)
+{
+ GetMethodsResponse *resp = (GetMethodsResponse*)msg;
+ GList *l;
+ EList *methods = e_list_new ((EListCopyFunc) g_strdup,
+ (EListFreeFunc) g_free,
+ NULL);
+
+ for (l = resp->methods; l; l = l->next)
+ e_list_append (methods, l->data);
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, methods, resp->closure);
+
+ g_object_unref (methods);
+}
+
+static void
+_get_methods_response_dtor (EBookMsg *msg)
+{
+ GetMethodsResponse *resp = (GetMethodsResponse*)msg;
+
+ g_list_foreach (resp->methods, (GFunc)g_free, NULL);
+ g_list_free (resp->methods);
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_get_methods_handler (EBookMsg *msg)
+{
+ GetMethodsMsg *methods_msg = (GetMethodsMsg *)msg;
+ GetMethodsResponse *response;
+ GError *error = NULL;
+
+ response = g_new (GetMethodsResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _get_methods_response_handler, _get_methods_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_supported_auth_methods (methods_msg->book, &response->methods, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+
+ response->book = methods_msg->book;
+ response->cb = methods_msg->cb;
+ response->closure = methods_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+guint
+e_book_async_get_supported_auth_methods (EBook *book,
+ EBookAuthMethodsCallback cb,
+ gpointer closure)
+{
+ GetMethodsMsg *msg;
+
+ init_async ();
+
+ msg = g_new (GetMethodsMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _get_methods_handler, (EBookMsgDtor)g_free);
+
+ msg->book = g_object_ref (book);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ char *user;
+ char *passwd;
+ char *auth_method;
+ EBookCallback cb;
+ gpointer closure;
+} AuthUserMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookCallback cb;
+ gpointer closure;
+} AuthUserResponse;
+
+static void
+_auth_user_response_handler (EBookMsg *msg)
+{
+ AuthUserResponse *resp = (AuthUserResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->closure);
+}
+
+static void
+_auth_user_response_dtor (EBookMsg *msg)
+{
+ AuthUserResponse *resp = (AuthUserResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_auth_user_handler (EBookMsg *msg)
+{
+ AuthUserMsg *auth_msg = (AuthUserMsg *)msg;
+ AuthUserResponse *response;
+ GError *error = NULL;
+
+ response = g_new (AuthUserResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _auth_user_response_handler, _auth_user_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_authenticate_user (auth_msg->book, auth_msg->user, auth_msg->passwd, auth_msg->auth_method, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = auth_msg->book;
+ response->cb = auth_msg->cb;
+ response->closure = auth_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_auth_user_dtor (EBookMsg *msg)
+{
+ AuthUserMsg *auth_msg = (AuthUserMsg *)msg;
+
+ g_free (auth_msg->user);
+ g_free (auth_msg->passwd);
+ g_free (auth_msg->auth_method);
+
+ g_free (auth_msg);
+}
+
+/* User authentication. */
+void
+e_book_async_authenticate_user (EBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method,
+ EBookCallback cb,
+ gpointer closure)
+{
+ AuthUserMsg *msg;
+
+ init_async ();
+
+ msg = g_new (AuthUserMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _auth_user_handler, _auth_user_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->user = g_strdup (user);
+ msg->passwd = g_strdup (passwd);
+ msg->auth_method = g_strdup (auth_method);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ char *id;
+ EBookContactCallback cb;
+ gpointer closure;
+} GetContactMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EContact *contact;
+ EBookStatus status;
+ EBookContactCallback cb;
+ gpointer closure;
+} GetContactResponse;
+
+static void
+_get_contact_response_handler (EBookMsg *msg)
+{
+ GetContactResponse *resp = (GetContactResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->contact, resp->closure);
+}
+
+static void
+_get_contact_response_dtor (EBookMsg *msg)
+{
+ GetContactResponse *resp = (GetContactResponse*)msg;
+
+ g_object_unref (resp->contact);
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_get_contact_handler (EBookMsg *msg)
+{
+ GetContactMsg *get_contact_msg = (GetContactMsg *)msg;
+ GetContactResponse *response;
+ GError *error = NULL;
+
+ response = g_new (GetContactResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _get_contact_response_handler, _get_contact_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_contact (get_contact_msg->book, get_contact_msg->id, &response->contact, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = get_contact_msg->book;
+ response->cb = get_contact_msg->cb;
+ response->closure = get_contact_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_get_contact_dtor (EBookMsg *msg)
+{
+ GetContactMsg *get_contact_msg = (GetContactMsg *)msg;
+
+ g_free (get_contact_msg->id);
+ g_free (get_contact_msg);
+}
+
+/* Fetching contacts. */
+guint
+e_book_async_get_contact (EBook *book,
+ const char *id,
+ EBookContactCallback cb,
+ gpointer closure)
+{
+ GetContactMsg *msg;
+
+ init_async ();
+
+ msg = g_new (GetContactMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _get_contact_handler, _get_contact_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->id = g_strdup (id);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
+
+
+
+/* Deleting cards. */
+gboolean
+e_book_async_remove_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure)
+{
+ const char *id = e_contact_get_const (contact, E_CONTACT_UID);
+
+ return e_book_async_remove_contact_by_id (book, id, cb, closure);
+}
+
+gboolean
+e_book_async_remove_contact_by_id (EBook *book,
+ const char *id,
+ EBookCallback cb,
+ gpointer closure)
+{
+ GList *list = g_list_append (NULL, g_strdup (id));
+
+ return e_book_async_remove_contacts (book, list, cb, closure);
+}
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ GList *id_list;
+ EBookCallback cb;
+ gpointer closure;
+} RemoveContactsMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookCallback cb;
+ gpointer closure;
+} RemoveContactsResponse;
+
+static void
+_remove_contacts_response_handler (EBookMsg *msg)
+{
+ RemoveContactsResponse *resp = (RemoveContactsResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->closure);
+}
+
+static void
+_remove_contacts_response_dtor (EBookMsg *msg)
+{
+ RemoveContactsResponse *resp = (RemoveContactsResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_remove_contacts_handler (EBookMsg *msg)
+{
+ RemoveContactsMsg *remove_contacts_msg = (RemoveContactsMsg *)msg;
+ RemoveContactsResponse *response;
+ GError *error = NULL;
+
+ response = g_new (RemoveContactsResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _remove_contacts_response_handler, _remove_contacts_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_remove_contacts (remove_contacts_msg->book, remove_contacts_msg->id_list, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = remove_contacts_msg->book;
+ response->cb = remove_contacts_msg->cb;
+ response->closure = remove_contacts_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_remove_contacts_dtor (EBookMsg *msg)
+{
+ RemoveContactsMsg *remove_contacts_msg = (RemoveContactsMsg *)msg;
+
+ g_list_foreach (remove_contacts_msg->id_list, (GFunc)g_free, NULL);
+ g_list_free (remove_contacts_msg->id_list);
+ g_free (remove_contacts_msg);
+}
+
+gboolean
+e_book_async_remove_contacts (EBook *book,
+ GList *id_list,
+ EBookCallback cb,
+ gpointer closure)
+{
+ RemoveContactsMsg *msg;
+ GList *l;
+ init_async ();
+
+ msg = g_new (RemoveContactsMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _remove_contacts_handler, _remove_contacts_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->id_list = g_list_copy (id_list);
+ for (l = msg->id_list; l; l = l->next)
+ l->data = g_strdup (l->data);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
+
+
+
+/* Adding contacts. */
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EContact *contact;
+ EBookIdCallback cb;
+ gpointer closure;
+} AddContactMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ char *id;
+ EBookStatus status;
+ EBookIdCallback cb;
+ gpointer closure;
+} AddContactResponse;
+
+static void
+_add_contact_response_handler (EBookMsg *msg)
+{
+ AddContactResponse *resp = (AddContactResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->id, resp->closure);
+}
+
+static void
+_add_contact_response_dtor (EBookMsg *msg)
+{
+ AddContactResponse *resp = (AddContactResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp->id);
+ g_free (resp);
+}
+
+static void
+_add_contact_handler (EBookMsg *msg)
+{
+ AddContactMsg *add_contact_msg = (AddContactMsg *)msg;
+ AddContactResponse *response;
+ GError *error = NULL;
+
+ response = g_new (AddContactResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _add_contact_response_handler, _add_contact_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_add_contact (add_contact_msg->book, add_contact_msg->contact, &error)) {
+ response->status = error->code;
+ response->id = NULL;
+ g_error_free (error);
+ }
+ else {
+ response->id = e_contact_get (add_contact_msg->contact, E_CONTACT_UID);
+ }
+ response->book = add_contact_msg->book;
+ response->cb = add_contact_msg->cb;
+ response->closure = add_contact_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_add_contact_dtor (EBookMsg *msg)
+{
+ AddContactMsg *add_contact_msg = (AddContactMsg *)msg;
+
+ g_object_unref (add_contact_msg->contact);
+ g_free (add_contact_msg);
+}
+
+gboolean
+e_book_async_add_contact (EBook *book,
+ EContact *contact,
+ EBookIdCallback cb,
+ gpointer closure)
+{
+ AddContactMsg *msg;
+
+ init_async ();
+
+ msg = g_new (AddContactMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _add_contact_handler, _add_contact_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->contact = g_object_ref (contact); /* XXX maybe we should _duplicate it here instead */
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return TRUE;
+}
+
+
+
+/* Modifying cards. */
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EContact *contact;
+ EBookCallback cb;
+ gpointer closure;
+} CommitContactMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookCallback cb;
+ gpointer closure;
+} CommitContactResponse;
+
+static void
+_commit_contact_response_handler (EBookMsg *msg)
+{
+ CommitContactResponse *resp = (CommitContactResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->closure);
+}
+
+static void
+_commit_contact_response_dtor (EBookMsg *msg)
+{
+ CommitContactResponse *resp = (CommitContactResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_commit_contact_handler (EBookMsg *msg)
+{
+ CommitContactMsg *commit_contact_msg = (CommitContactMsg *)msg;
+ CommitContactResponse *response;
+ GError *error = NULL;
+
+ response = g_new (CommitContactResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _commit_contact_response_handler, _commit_contact_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_commit_contact (commit_contact_msg->book, commit_contact_msg->contact, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = commit_contact_msg->book;
+ response->cb = commit_contact_msg->cb;
+ response->closure = commit_contact_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_commit_contact_dtor (EBookMsg *msg)
+{
+ CommitContactMsg *commit_contact_msg = (CommitContactMsg *)msg;
+
+ g_object_unref (commit_contact_msg->contact);
+ g_free (commit_contact_msg);
+}
+
+
+gboolean
+e_book_async_commit_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure)
+{
+ CommitContactMsg *msg;
+
+ init_async ();
+
+ msg = g_new (CommitContactMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _commit_contact_handler, _commit_contact_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->contact = g_object_ref (contact); /* XXX maybe we should _duplicate it here instead */
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return TRUE;
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookQuery *query;
+ EBookBookViewCallback cb;
+ gpointer closure;
+} GetBookViewMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ EBookView *book_view;
+ EBookBookViewCallback cb;
+ gpointer closure;
+} GetBookViewResponse;
+
+static void
+_get_book_view_response_handler (EBookMsg *msg)
+{
+ GetBookViewResponse *resp = (GetBookViewResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->book_view, resp->closure);
+}
+
+static void
+_get_book_view_response_dtor (EBookMsg *msg)
+{
+ GetBookViewResponse *resp = (GetBookViewResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_get_book_view_handler (EBookMsg *msg)
+{
+ GetBookViewMsg *view_msg = (GetBookViewMsg *)msg;
+ GetBookViewResponse *response;
+ GError *error = NULL;
+
+ response = g_new (GetBookViewResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _get_book_view_response_handler, _get_book_view_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_book_view (view_msg->book, view_msg->query, NULL, -1, &response->book_view, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = view_msg->book;
+ response->cb = view_msg->cb;
+ response->closure = view_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_get_book_view_dtor (EBookMsg *msg)
+{
+ GetBookViewMsg *view_msg = (GetBookViewMsg *)msg;
+
+ e_book_query_unref (view_msg->query);
+ g_free (view_msg);
+}
+
+guint
+e_book_async_get_book_view (EBook *book,
+ const gchar *query,
+ EBookBookViewCallback cb,
+ gpointer closure)
+{
+ GetBookViewMsg *msg;
+
+ init_async ();
+
+ msg = g_new (GetBookViewMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _get_book_view_handler, _get_book_view_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->query = e_book_query_from_string (query);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
+
+
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookQuery *query;
+ EBookContactsCallback cb;
+ gpointer closure;
+} GetContactsMsg;
+
+typedef struct {
+ EBookMsg msg;
+
+ EBook *book;
+ EBookStatus status;
+ GList *contacts;
+ EBookContactsCallback cb;
+ gpointer closure;
+} GetContactsResponse;
+
+static void
+_get_contacts_response_handler (EBookMsg *msg)
+{
+ GetContactsResponse *resp = (GetContactsResponse*)msg;
+
+ if (resp->cb)
+ resp->cb (resp->book, resp->status, resp->contacts, resp->closure);
+}
+
+static void
+_get_contacts_response_dtor (EBookMsg *msg)
+{
+ GetContactsResponse *resp = (GetContactsResponse*)msg;
+
+ g_object_unref (resp->book);
+ g_free (resp);
+}
+
+static void
+_get_contacts_handler (EBookMsg *msg)
+{
+ GetContactsMsg *view_msg = (GetContactsMsg *)msg;
+ GetContactsResponse *response;
+ GError *error = NULL;
+
+ response = g_new (GetContactsResponse, 1);
+ e_book_msg_init ((EBookMsg*)response, _get_contacts_response_handler, _get_contacts_response_dtor);
+
+ response->status = E_BOOK_ERROR_OK;
+ if (!e_book_get_contacts (view_msg->book, view_msg->query, &response->contacts, &error)) {
+ response->status = error->code;
+ g_error_free (error);
+ }
+ response->book = view_msg->book;
+ response->cb = view_msg->cb;
+ response->closure = view_msg->closure;
+
+ g_async_queue_push (from_worker_queue, response);
+}
+
+static void
+_get_contacts_dtor (EBookMsg *msg)
+{
+ GetContactsMsg *view_msg = (GetContactsMsg *)msg;
+
+ e_book_query_unref (view_msg->query);
+ g_free (view_msg);
+}
+
+guint
+e_book_async_get_contacts (EBook *book,
+ const gchar *query,
+ EBookContactsCallback cb,
+ gpointer closure)
+{
+ GetContactsMsg *msg;
+
+ init_async ();
+
+ msg = g_new (GetContactsMsg, 1);
+ e_book_msg_init ((EBookMsg*)msg, _get_contacts_handler, _get_contacts_dtor);
+
+ msg->book = g_object_ref (book);
+ msg->query = e_book_query_from_string (query);
+ msg->cb = cb;
+ msg->closure = closure;
+
+ g_async_queue_push (to_worker_queue, msg);
+
+ return 0;
+}
diff --git a/addressbook/backend/ebook/e-book-async.h b/addressbook/backend/ebook/e-book-async.h
new file mode 100644
index 0000000000..097f3cff61
--- /dev/null
+++ b/addressbook/backend/ebook/e-book-async.h
@@ -0,0 +1,107 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * The Evolution addressbook client object.
+ *
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ *
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#ifndef __E_BOOK_ASYNC_H__
+#define __E_BOOK_ASYNC_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <e-util/e-list.h>
+#include <ebook/e-contact.h>
+#include <ebook/e-book.h>
+
+G_BEGIN_DECLS
+
+/* Callbacks for asynchronous functions. */
+typedef void (*EBookCallback) (EBook *book, EBookStatus status, gpointer closure);
+typedef void (*EBookOpenProgressCallback) (EBook *book,
+ const char *status_message,
+ short percent,
+ gpointer closure);
+typedef void (*EBookIdCallback) (EBook *book, EBookStatus status, const char *id, gpointer closure);
+typedef void (*EBookContactCallback) (EBook *book, EBookStatus status, EContact *contact, gpointer closure);
+typedef void (*EBookContactsCallback) (EBook *book, EBookStatus status, GList *contacts, gpointer closure);
+typedef void (*EBookBookViewCallback) (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure);
+typedef void (*EBookFieldsCallback) (EBook *book, EBookStatus status, EList *fields, gpointer closure);
+typedef void (*EBookAuthMethodsCallback) (EBook *book, EBookStatus status, EList *auth_methods, gpointer closure);
+
+void e_book_async_load_uri (EBook *book,
+ const char *uri,
+ EBookCallback open_response,
+ gpointer closure);
+
+void e_book_async_get_default_addressbook (EBookCallback open_response,
+ gpointer closure);
+
+void e_book_async_unload_uri (EBook *book);
+
+guint e_book_async_get_supported_fields (EBook *book,
+ EBookFieldsCallback cb,
+ gpointer closure);
+
+guint e_book_async_get_supported_auth_methods (EBook *book,
+ EBookAuthMethodsCallback cb,
+ gpointer closure);
+
+/* User authentication. */
+void e_book_async_authenticate_user (EBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method,
+ EBookCallback cb,
+ gpointer closure);
+
+/* Fetching cards. */
+guint e_book_async_get_contact (EBook *book,
+ const char *id,
+ EBookContactCallback cb,
+ gpointer closure);
+
+guint e_book_async_get_contacts (EBook *book,
+ const char *query,
+ EBookContactsCallback cb,
+ gpointer closure);
+
+/* Deleting cards. */
+gboolean e_book_async_remove_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure);
+gboolean e_book_async_remove_contact_by_id (EBook *book,
+ const char *id,
+ EBookCallback cb,
+ gpointer closure);
+
+gboolean e_book_async_remove_contacts (EBook *book,
+ GList *id_list,
+ EBookCallback cb,
+ gpointer closure);
+
+/* Adding cards. */
+gboolean e_book_async_add_contact (EBook *book,
+ EContact *contact,
+ EBookIdCallback cb,
+ gpointer closure);
+
+/* Modifying cards. */
+gboolean e_book_async_commit_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure);
+
+guint e_book_async_get_book_view (EBook *book,
+ const gchar *query, /* XXX this needs to change to an EBookQuery */
+ EBookBookViewCallback cb,
+ gpointer closure);
+
+G_END_DECLS
+
+#endif /* ! __E_BOOK_H__ */
diff --git a/addressbook/backend/ebook/e-book-listener.c b/addressbook/backend/ebook/e-book-listener.c
index 9d6d876045..0bb5193376 100644
--- a/addressbook/backend/ebook/e-book-listener.c
+++ b/addressbook/backend/ebook/e-book-listener.c
@@ -11,13 +11,14 @@
#include <config.h>
#include <bonobo/bonobo-main.h>
+#include "e-contact.h"
#include "e-book-listener.h"
#include "e-book-marshal.h"
-static EBookStatus e_book_listener_convert_status (GNOME_Evolution_Addressbook_BookListener_CallStatus status);
+static EBookStatus e_book_listener_convert_status (GNOME_Evolution_Addressbook_CallStatus status);
enum {
- RESPONSES_QUEUED,
+ RESPONSE,
LAST_SIGNAL
};
@@ -26,569 +27,267 @@ static guint e_book_listener_signals [LAST_SIGNAL];
static BonoboObjectClass *parent_class;
struct _EBookListenerPrivate {
- GList *response_queue;
- gint timeout_id;
-
- guint timeout_lock : 1;
guint stopped : 1;
};
-static void
-response_free (EBookListenerResponse *resp)
-{
- if (resp == NULL)
- return;
-
- g_free (resp->msg);
- g_free (resp->id);
-
- if (resp->book != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (resp->book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_listener_destroy: "
- "Exception destroying book "
- "in response queue!\n");
- }
-
- CORBA_exception_free (&ev);
- }
-
- if (resp->cursor != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (resp->cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_listener_destroy: "
- "Exception destroying cursor "
- "in response queue!\n");
- }
-
- CORBA_exception_free (&ev);
- }
-
- if (resp->book_view != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (resp->book_view, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_listener_destroy: "
- "Exception destroying book_view "
- "in response queue!\n");
- }
-
- CORBA_exception_free (&ev);
- }
-
- g_free (resp);
-}
-
-static gboolean
-e_book_listener_check_queue (EBookListener *listener)
-{
- if (listener->priv->timeout_lock)
- return TRUE;
-
- listener->priv->timeout_lock = TRUE;
-
- if (listener->priv->response_queue != NULL && !listener->priv->stopped) {
- g_signal_emit (listener, e_book_listener_signals [RESPONSES_QUEUED], 0);
- }
-
- if (listener->priv->response_queue == NULL || listener->priv->stopped) {
- listener->priv->timeout_id = 0;
- listener->priv->timeout_lock = FALSE;
- bonobo_object_unref (BONOBO_OBJECT (listener)); /* release the timeout's reference */
- return FALSE;
- }
-
- listener->priv->timeout_lock = FALSE;
- return TRUE;
-}
-
-static void
-e_book_listener_queue_response (EBookListener *listener,
- EBookListenerResponse *response)
+static EBookStatus
+e_book_listener_convert_status (const GNOME_Evolution_Addressbook_CallStatus status)
{
- if (response == NULL)
- return;
-
- if (listener->priv->stopped) {
- response_free (response);
- return;
- }
-
- listener->priv->response_queue = g_list_append (listener->priv->response_queue, response);
-
- if (listener->priv->timeout_id == 0) {
-
- /* 20 == an arbitrary small integer */
- listener->priv->timeout_id = g_timeout_add (20, (GSourceFunc) e_book_listener_check_queue, listener);
-
- /* Hold a reference on behalf of the timeout */
- bonobo_object_ref (BONOBO_OBJECT (listener));
-
+ switch (status) {
+ case GNOME_Evolution_Addressbook_Success:
+ return E_BOOK_ERROR_OK;
+ case GNOME_Evolution_Addressbook_RepositoryOffline:
+ return E_BOOK_ERROR_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Addressbook_PermissionDenied:
+ return E_BOOK_ERROR_PERMISSION_DENIED;
+ case GNOME_Evolution_Addressbook_ContactNotFound:
+ return E_BOOK_ERROR_CONTACT_NOT_FOUND;
+ case GNOME_Evolution_Addressbook_ContactIdAlreadyExists:
+ return E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Addressbook_AuthenticationFailed:
+ return E_BOOK_ERROR_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Addressbook_AuthenticationRequired:
+ return E_BOOK_ERROR_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Addressbook_TLSNotAvailable:
+ return E_BOOK_ERROR_TLS_NOT_AVAILABLE;
+ case GNOME_Evolution_Addressbook_NoSuchBook:
+ return E_BOOK_ERROR_NO_SUCH_BOOK;
+ case GNOME_Evolution_Addressbook_OtherError:
+ default:
+ return E_BOOK_ERROR_OTHER_ERROR;
}
}
-/* Add, Remove, Modify */
-static void
-e_book_listener_queue_generic_response (EBookListener *listener,
- EBookListenerOperation op,
- EBookStatus status)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = op;
- resp->status = status;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_open_response (EBookListener *listener,
- EBookStatus status,
- GNOME_Evolution_Addressbook_Book book)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = OpenBookResponse;
- resp->status = status;
- resp->book = book;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_open_progress (EBookListener *listener,
- const char *msg,
- short percent)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = OpenProgressEvent;
- resp->msg = g_strdup (msg);
- resp->percent = percent;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-
-static void
-e_book_listener_queue_create_card_response (EBookListener *listener,
- EBookStatus status,
- const char *id)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = CreateCardResponse;
- resp->status = status;
- resp->id = g_strdup (id);
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_get_vcard_response (EBookListener *listener,
- EBookStatus status,
- const char *vcard)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = GetCardResponse;
- resp->status = status;
- resp->vcard = g_strdup (vcard);
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_get_cursor_response (EBookListener *listener,
- EBookStatus status,
- GNOME_Evolution_Addressbook_CardCursor cursor)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = GetCursorResponse;
- resp->status = status;
- resp->cursor = cursor;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_get_view_response (EBookListener *listener,
- EBookStatus status,
- GNOME_Evolution_Addressbook_BookView book_view)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = GetBookViewResponse;
- resp->status = status;
- resp->book_view = book_view;
-
- e_book_listener_queue_response (listener, resp);
-}
-
static void
-e_book_listener_queue_get_changes_response (EBookListener *listener,
- EBookStatus status,
- GNOME_Evolution_Addressbook_BookView book_view)
+impl_BookListener_respond_create_contact (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const CORBA_char* id,
+ CORBA_Environment *ev)
{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = GetChangesResponse;
- resp->status = status;
- resp->book_view = book_view;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_link_status (EBookListener *listener,
- gboolean connected)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- resp = g_new0 (EBookListenerResponse, 1);
+ response.op = CreateContactResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.id = g_strdup (id);
- resp->op = LinkStatusEvent;
- resp->connected = connected;
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
- e_book_listener_queue_response (listener, resp);
+ g_free (response.id);
}
static void
-e_book_listener_queue_writable_status (EBookListener *listener,
- gboolean writable)
+impl_BookListener_respond_remove_contacts (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ CORBA_Environment *ev)
{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- resp->op = WritableStatusEvent;
- resp->writable = writable;
+ response.op = RemoveContactResponse;
+ response.status = e_book_listener_convert_status (status);
- e_book_listener_queue_response (listener, resp);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
-e_book_listener_queue_authentication_response (EBookListener *listener,
- EBookStatus status)
+impl_BookListener_respond_modify_contact (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ CORBA_Environment *ev)
{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- resp->op = AuthenticationResponse;
- resp->status = status;
+ response.op = ModifyContactResponse;
+ response.status = e_book_listener_convert_status (status);
- e_book_listener_queue_response (listener, resp);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
-e_book_listener_queue_get_supported_fields_response (EBookListener *listener,
- EBookStatus status,
- const GNOME_Evolution_Addressbook_stringlist *fields)
+impl_BookListener_respond_get_contact (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const CORBA_char* card,
+ CORBA_Environment *ev)
{
- EBookListenerResponse *resp;
- int i;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- resp->op = GetSupportedFieldsResponse;
- resp->status = status;
- resp->list = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
+ response.op = GetContactResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.vcard = g_strdup (card);
- for (i = 0; i < fields->_length; i ++) {
- e_list_append (resp->list, fields->_buffer[i]);
- }
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
- e_book_listener_queue_response (listener, resp);
+ g_free (response.vcard);
}
static void
-e_book_listener_queue_get_supported_auth_methods_response (EBookListener *listener,
- EBookStatus status,
- const GNOME_Evolution_Addressbook_stringlist *auth_methods)
+impl_BookListener_respond_get_contact_list (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const GNOME_Evolution_Addressbook_stringlist *cards,
+ CORBA_Environment *ev)
{
- EBookListenerResponse *resp;
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
int i;
if (listener->priv->stopped)
return;
- resp = g_new0 (EBookListenerResponse, 1);
+ response.op = GetContactListResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.list = NULL;
- resp->op = GetSupportedAuthMethodsResponse;
- resp->status = status;
- resp->list = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
-
- for (i = 0; i < auth_methods->_length; i ++) {
- e_list_append (resp->list, auth_methods->_buffer[i]);
+ for (i = 0; i < cards->_length; i ++) {
+ response.list = g_list_prepend (response.list, e_contact_new_from_vcard (cards->_buffer[i]));
}
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-impl_BookListener_respond_create_card (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const CORBA_char* id,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
-
- e_book_listener_queue_create_card_response (
- listener,
- e_book_listener_convert_status (status),
- id);
-}
-
-static void
-impl_BookListener_respond_remove_cards (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
-
- e_book_listener_queue_generic_response (
- listener, RemoveCardResponse,
- e_book_listener_convert_status (status));
-}
-
-static void
-impl_BookListener_respond_modify_card (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
-
- e_book_listener_queue_generic_response (
- listener, ModifyCardResponse,
- e_book_listener_convert_status (status));
-}
-
-static void
-impl_BookListener_respond_get_vcard (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const CORBA_char* card,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
-
- e_book_listener_queue_get_vcard_response (
- listener,
- e_book_listener_convert_status (status),
- g_strdup (card));
-}
-
-static void
-impl_BookListener_respond_get_cursor (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_CardCursor cursor,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
- GNOME_Evolution_Addressbook_CardCursor cursor_copy;
-
- cursor_copy = bonobo_object_dup_ref (cursor, ev);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating CardCursor!\n");
- return;
- }
-
- e_book_listener_queue_get_cursor_response (
- listener,
- e_book_listener_convert_status (status),
- cursor_copy);
+ /* XXX free response.list? */
}
static void
impl_BookListener_respond_get_view (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ const GNOME_Evolution_Addressbook_CallStatus status,
const GNOME_Evolution_Addressbook_BookView book_view,
CORBA_Environment *ev)
{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
- GNOME_Evolution_Addressbook_BookView book_view_copy;
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- book_view_copy = bonobo_object_dup_ref (book_view, ev);
+ printf ("impl_BookListener_respond_get_view\n");
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating BookView.\n");
+ if (listener->priv->stopped)
return;
- }
- e_book_listener_queue_get_view_response (
- listener,
- e_book_listener_convert_status (status),
- book_view_copy);
+ response.op = GetBookViewResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.book_view = bonobo_object_dup_ref (book_view, ev);
+
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
impl_BookListener_respond_get_changes (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_BookView book_view,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const GNOME_Evolution_Addressbook_BookChangeList *changes,
CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
- GNOME_Evolution_Addressbook_BookView book_view_copy;
+ EBookListenerResponse response;
+ int i;
- book_view_copy = bonobo_object_dup_ref (book_view, ev);
+ response.op = GetChangesResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.list = NULL;
+
+ for (i = 0; i < changes->_length; i ++) {
+ EBookChange *change = g_new (EBookChange, 1);
+ GNOME_Evolution_Addressbook_BookChangeItem corba_change = changes->_buffer[i];
+
+ switch (corba_change._d) {
+ case GNOME_Evolution_Addressbook_ContactAdded:
+ change->change_type = E_BOOK_CHANGE_CARD_ADDED;
+ change->vcard = g_strdup (corba_change._u.add_vcard);
+ break;
+ case GNOME_Evolution_Addressbook_ContactDeleted:
+ change->change_type = E_BOOK_CHANGE_CARD_DELETED;
+ change->id = g_strdup (corba_change._u.del_id);
+ break;
+ case GNOME_Evolution_Addressbook_ContactModified:
+ change->change_type = E_BOOK_CHANGE_CARD_MODIFIED;
+ change->vcard = g_strdup (corba_change._u.mod_vcard);
+ break;
+ }
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating BookView.\n");
- return;
+ response.list = g_list_prepend (response.list, change);
}
- e_book_listener_queue_get_changes_response (
- listener,
- e_book_listener_convert_status (status),
- book_view_copy);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
impl_BookListener_respond_open_book (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_Book book,
+ const GNOME_Evolution_Addressbook_CallStatus status,
CORBA_Environment *ev)
{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
- GNOME_Evolution_Addressbook_Book book_copy;
-
- book_copy = bonobo_object_dup_ref (book, ev);
+ EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating Book!\n");
- return;
- }
+ response.op = OpenBookResponse;
+ response.status = e_book_listener_convert_status (status);
- e_book_listener_queue_open_response (
- listener,
- e_book_listener_convert_status (status),
- book_copy);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
-impl_BookListener_report_open_book_progress (PortableServer_Servant servant,
- const CORBA_char *status_message,
- const CORBA_short percent,
- CORBA_Environment *ev)
+impl_BookListener_respond_remove_book (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- e_book_listener_queue_open_progress (
- listener, status_message, percent);
+ response.op = RemoveBookResponse;
+ response.status = e_book_listener_convert_status (status);
+
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
impl_BookListener_respond_authentication_result (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ const GNOME_Evolution_Addressbook_CallStatus status,
CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
+
+ response.op = AuthenticationResponse;
+ response.status = e_book_listener_convert_status (status);
- e_book_listener_queue_authentication_response (
- listener, status);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
-impl_BookListener_response_get_supported_fields (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_stringlist *fields,
- CORBA_Environment *ev)
+impl_BookListener_respond_get_supported_fields (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const GNOME_Evolution_Addressbook_stringlist *fields,
+ CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
+ int i;
- e_book_listener_queue_get_supported_fields_response (
- listener, status, fields);
-}
+ response.op = GetSupportedFieldsResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.list = NULL;
-static void
-impl_BookListener_response_get_supported_auth_methods (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_stringlist *auth_methods,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ for (i = 0; i < fields->_length; i ++)
+ response.list = g_list_prepend (response.list, g_strdup (fields->_buffer[i]));
- e_book_listener_queue_get_supported_auth_methods_response (
- listener, status, auth_methods);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
-impl_BookListener_report_connection_status (PortableServer_Servant servant,
- const CORBA_boolean connected,
- CORBA_Environment *ev)
+impl_BookListener_respond_get_supported_auth_methods (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_CallStatus status,
+ const GNOME_Evolution_Addressbook_stringlist *auth_methods,
+ CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
+ int i;
+
+ response.op = GetSupportedAuthMethodsResponse;
+ response.status = e_book_listener_convert_status (status);
+ response.list = NULL;
- e_book_listener_queue_link_status (
- listener, connected);
+ for (i = 0; i < auth_methods->_length; i ++)
+ response.list = g_list_prepend (response.list, g_strdup (auth_methods->_buffer[i]));
+
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
static void
@@ -597,89 +296,20 @@ impl_BookListener_report_writable (PortableServer_Servant servant,
CORBA_Environment *ev)
{
EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant));
+ EBookListenerResponse response;
- e_book_listener_queue_writable_status (listener, writable);
-}
+ response.op = WritableStatusEvent;
+ response.writable = writable;
-/**
- * e_book_listener_check_pending:
- * @listener: the #EBookListener
- *
- * Returns: the number of items on the response queue,
- * or -1 if the @listener is isn't an #EBookListener.
- */
-int
-e_book_listener_check_pending (EBookListener *listener)
-{
- g_return_val_if_fail (listener != NULL, -1);
- g_return_val_if_fail (E_IS_BOOK_LISTENER (listener), -1);
-
- return g_list_length (listener->priv->response_queue);
+ g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response);
}
-/**
- * e_book_listener_pop_response:
- * @listener: the #EBookListener for which a request is to be popped
- *
- * Returns: an #EBookListenerResponse if there are responses on the
- * queue to be returned; %NULL if there aren't, or if the @listener
- * isn't an EBookListener.
- */
-EBookListenerResponse *
-e_book_listener_pop_response (EBookListener *listener)
-{
- EBookListenerResponse *resp;
- GList *popped;
-
- g_return_val_if_fail (listener != NULL, NULL);
- g_return_val_if_fail (E_IS_BOOK_LISTENER (listener), NULL);
-
- if (listener->priv->response_queue == NULL)
- return NULL;
-
- resp = listener->priv->response_queue->data;
-
- popped = listener->priv->response_queue;
- listener->priv->response_queue =
- g_list_remove_link (listener->priv->response_queue,
- listener->priv->response_queue);
- g_list_free_1 (popped);
-
- return resp;
-}
-
-static EBookStatus
-e_book_listener_convert_status (const GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+static void
+impl_BookListener_respond_progress (PortableServer_Servant servant,
+ const CORBA_char * message,
+ const CORBA_short percent,
+ CORBA_Environment *ev)
{
- switch (status) {
- case GNOME_Evolution_Addressbook_BookListener_Success:
- return E_BOOK_STATUS_SUCCESS;
- case GNOME_Evolution_Addressbook_BookListener_RepositoryOffline:
- return E_BOOK_STATUS_REPOSITORY_OFFLINE;
- case GNOME_Evolution_Addressbook_BookListener_PermissionDenied:
- return E_BOOK_STATUS_PERMISSION_DENIED;
- case GNOME_Evolution_Addressbook_BookListener_CardNotFound:
- return E_BOOK_STATUS_CARD_NOT_FOUND;
- case GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists:
- return E_BOOK_STATUS_CARD_ID_ALREADY_EXISTS;
- case GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported:
- return E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED;
- case GNOME_Evolution_Addressbook_BookListener_AuthenticationFailed:
- return E_BOOK_STATUS_AUTHENTICATION_FAILED;
- case GNOME_Evolution_Addressbook_BookListener_AuthenticationRequired:
- return E_BOOK_STATUS_AUTHENTICATION_REQUIRED;
- case GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable:
- return E_BOOK_STATUS_TLS_NOT_AVAILABLE;
- case GNOME_Evolution_Addressbook_BookListener_NoSuchBook:
- return E_BOOK_STATUS_NO_SUCH_BOOK;
- case GNOME_Evolution_Addressbook_BookListener_OtherError:
- return E_BOOK_STATUS_OTHER_ERROR;
- default:
- g_warning ("e_book_listener_convert_status: Unknown status "
- "from card server: %d\n", (int) status);
- return E_BOOK_STATUS_UNKNOWN;
-
- }
}
static void
@@ -701,7 +331,9 @@ e_book_listener_new ()
{
EBookListener *listener;
- listener = g_object_new (E_TYPE_BOOK_LISTENER, NULL);
+ listener = g_object_new (E_TYPE_BOOK_LISTENER,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_ALL_AT_IDLE, NULL),
+ NULL);
e_book_listener_construct (listener);
@@ -723,38 +355,6 @@ e_book_listener_stop (EBookListener *listener)
}
static void
-e_book_listener_dispose (GObject *object)
-{
- EBookListener *listener = E_BOOK_LISTENER (object);
-
- if (listener->priv) {
- GList *l;
-
- /* Remove our response queue handler: In theory, this
- can never happen since we always hold a reference
- to the listener while the timeout is running. */
- if (listener->priv->timeout_id) {
- g_source_remove (listener->priv->timeout_id);
- }
-
- /* Clean up anything still sitting in response_queue */
- for (l = listener->priv->response_queue; l != NULL; l = l->next) {
- EBookListenerResponse *resp = l->data;
-
- response_free (resp);
- }
- g_list_free (listener->priv->response_queue);
-
- g_free (listener->priv);
-
- listener->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
e_book_listener_class_init (EBookListenerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -762,31 +362,30 @@ e_book_listener_class_init (EBookListenerClass *klass)
parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT);
- e_book_listener_signals [RESPONSES_QUEUED] =
- g_signal_new ("responses_queued",
+ e_book_listener_signals [RESPONSE] =
+ g_signal_new ("response",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookListenerClass, responses_queued),
+ G_STRUCT_OFFSET (EBookListenerClass, response),
NULL, NULL,
- e_book_marshal_NONE__NONE,
- G_TYPE_NONE, 0);
-
- object_class->dispose = e_book_listener_dispose;
+ e_book_marshal_NONE__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
epv = &klass->epv;
- epv->notifyOpenBookProgress = impl_BookListener_report_open_book_progress;
+ epv->notifyProgress = impl_BookListener_respond_progress;
epv->notifyBookOpened = impl_BookListener_respond_open_book;
- epv->notifyCardCreated = impl_BookListener_respond_create_card;
- epv->notifyCardsRemoved = impl_BookListener_respond_remove_cards;
- epv->notifyCardModified = impl_BookListener_respond_modify_card;
+ epv->notifyBookRemoved = impl_BookListener_respond_remove_book;
+ epv->notifyContactCreated = impl_BookListener_respond_create_contact;
+ epv->notifyContactsRemoved = impl_BookListener_respond_remove_contacts;
+ epv->notifyContactModified = impl_BookListener_respond_modify_contact;
epv->notifyAuthenticationResult = impl_BookListener_respond_authentication_result;
- epv->notifySupportedFields = impl_BookListener_response_get_supported_fields;
- epv->notifySupportedAuthMethods = impl_BookListener_response_get_supported_auth_methods;
- epv->notifyCardRequested = impl_BookListener_respond_get_vcard;
- epv->notifyCursorRequested = impl_BookListener_respond_get_cursor;
+ epv->notifySupportedFields = impl_BookListener_respond_get_supported_fields;
+ epv->notifySupportedAuthMethods = impl_BookListener_respond_get_supported_auth_methods;
+ epv->notifyContactRequested = impl_BookListener_respond_get_contact;
+ epv->notifyContactListRequested = impl_BookListener_respond_get_contact_list;
epv->notifyViewRequested = impl_BookListener_respond_get_view;
epv->notifyChangesRequested = impl_BookListener_respond_get_changes;
- epv->notifyConnectionStatus = impl_BookListener_report_connection_status;
epv->notifyWritable = impl_BookListener_report_writable;
}
diff --git a/addressbook/backend/ebook/e-book-listener.h b/addressbook/backend/ebook/e-book-listener.h
index 1b02dd4bb6..4d1f0c0231 100644
--- a/addressbook/backend/ebook/e-book-listener.h
+++ b/addressbook/backend/ebook/e-book-listener.h
@@ -15,7 +15,6 @@
#include <bonobo/bonobo-object.h>
#include <ebook/addressbook.h>
#include <ebook/e-book-types.h>
-#include <e-util/e-list.h>
#define E_TYPE_BOOK_LISTENER (e_book_listener_get_type ())
#define E_BOOK_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_LISTENER, EBookListener))
@@ -29,6 +28,7 @@ G_BEGIN_DECLS
typedef struct _EBookListener EBookListener;
typedef struct _EBookListenerClass EBookListenerClass;
typedef struct _EBookListenerPrivate EBookListenerPrivate;
+typedef struct _EBookListenerResponse EBookListenerResponse;
struct _EBookListener {
BonoboObject parent;
@@ -39,20 +39,30 @@ struct _EBookListenerClass {
BonoboObjectClass parent;
POA_GNOME_Evolution_Addressbook_BookListener__epv epv;
+
/*
* Signals
*/
- void (*responses_queued) (void);
+
+ void (*response) (EBookListener *listener, EBookListenerResponse *response);
+
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
};
typedef enum {
/* Async responses */
OpenBookResponse,
- CreateCardResponse,
- RemoveCardResponse,
- ModifyCardResponse,
- GetCardResponse,
- GetCursorResponse,
+ RemoveBookResponse,
+ CreateContactResponse,
+ RemoveContactResponse,
+ ModifyContactResponse,
+ GetContactResponse,
+ GetContactListResponse,
GetBookViewResponse,
GetChangesResponse,
AuthenticationResponse,
@@ -62,28 +72,22 @@ typedef enum {
/* Async events */
LinkStatusEvent,
WritableStatusEvent,
- OpenProgressEvent,
+ ProgressEvent,
} EBookListenerOperation;
-typedef struct {
+struct _EBookListenerResponse {
EBookListenerOperation op;
/* For most Response notifications */
EBookStatus status;
- /* For OpenBookResponse */
- GNOME_Evolution_Addressbook_Book book;
-
- /* For GetCursorResponse */
- GNOME_Evolution_Addressbook_CardCursor cursor;
-
/* For GetBookViewReponse */
GNOME_Evolution_Addressbook_BookView book_view;
/* For GetSupportedFields/GetSupportedAuthMethods */
- EList *list;
+ GList *list;
- /* For OpenProgressEvent */
+ /* For ProgressEvent */
char *msg;
short percent;
@@ -96,12 +100,10 @@ typedef struct {
/* For Card[Added|Removed|Modified]Event */
char *id;
char *vcard;
-} EBookListenerResponse;
+};
EBookListener *e_book_listener_new (void);
-int e_book_listener_check_pending (EBookListener *listener);
-EBookListenerResponse *e_book_listener_pop_response (EBookListener *listener);
GType e_book_listener_get_type (void);
void e_book_listener_stop (EBookListener *listener);
diff --git a/addressbook/backend/ebook/e-book-query.c b/addressbook/backend/ebook/e-book-query.c
new file mode 100644
index 0000000000..16e325303c
--- /dev/null
+++ b/addressbook/backend/ebook/e-book-query.c
@@ -0,0 +1,524 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <config.h>
+
+#include "e-book-query.h"
+#include <e-util/e-sexp.h>
+
+#include <stdarg.h>
+#include <string.h>
+
+typedef enum {
+ E_BOOK_QUERY_TYPE_AND,
+ E_BOOK_QUERY_TYPE_OR,
+ E_BOOK_QUERY_TYPE_NOT,
+ E_BOOK_QUERY_TYPE_FIELD_EXISTS,
+ E_BOOK_QUERY_TYPE_FIELD_TEST,
+ E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS
+} EBookQueryType;
+
+struct EBookQuery {
+ EBookQueryType type;
+ int ref_count;
+
+ union {
+ struct {
+ guint nqs;
+ EBookQuery **qs;
+ } andor;
+
+ struct {
+ EBookQuery *q;
+ } not;
+
+ struct {
+ EBookQueryTest test;
+ EContactField field;
+ char *value;
+ } field_test;
+
+ struct {
+ EContactField field;
+ } exist;
+
+ struct {
+ char *value;
+ } any_field_contains;
+ } query;
+};
+
+static EBookQuery *
+conjoin (EBookQueryType type, int nqs, EBookQuery **qs, gboolean unref)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+ int i;
+
+ ret->type = type;
+ ret->query.andor.nqs = nqs;
+ ret->query.andor.qs = g_new (EBookQuery *, nqs);
+ for (i = 0; i < nqs; i++) {
+ ret->query.andor.qs[i] = qs[i];
+ if (!unref)
+ e_book_query_ref (qs[i]);
+ }
+
+ return ret;
+}
+
+EBookQuery *
+e_book_query_and (int nqs, EBookQuery **qs, gboolean unref)
+{
+ return conjoin (E_BOOK_QUERY_TYPE_AND, nqs, qs, unref);
+}
+
+EBookQuery *
+e_book_query_or (int nqs, EBookQuery **qs, gboolean unref)
+{
+ return conjoin (E_BOOK_QUERY_TYPE_OR, nqs, qs, unref);
+}
+
+static EBookQuery *
+conjoinv (EBookQueryType type, EBookQuery *q, va_list ap)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+ GPtrArray *qs;
+
+ qs = g_ptr_array_new ();
+ while (q) {
+ g_ptr_array_add (qs, q);
+ q = va_arg (ap, EBookQuery *);
+ }
+ va_end (ap);
+
+ ret->type = type;
+ ret->query.andor.nqs = qs->len;
+ ret->query.andor.qs = (EBookQuery **)qs->pdata;
+ g_ptr_array_free (qs, FALSE);
+
+ return ret;
+}
+
+EBookQuery *
+e_book_query_andv (EBookQuery *q, ...)
+{
+ va_list ap;
+
+ va_start (ap, q);
+ return conjoinv (E_BOOK_QUERY_TYPE_AND, q, ap);
+}
+
+EBookQuery *
+e_book_query_orv (EBookQuery *q, ...)
+{
+ va_list ap;
+
+ va_start (ap, q);
+ return conjoinv (E_BOOK_QUERY_TYPE_OR, q, ap);
+}
+
+EBookQuery *
+e_book_query_not (EBookQuery *q, gboolean unref)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+
+ ret->type = E_BOOK_QUERY_TYPE_NOT;
+ ret->query.not.q = q;
+ if (!unref)
+ e_book_query_ref (q);
+
+ return ret;
+}
+
+EBookQuery *
+e_book_query_field_test (EContactField field,
+ EBookQueryTest test,
+ const char *value)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+
+ ret->type = E_BOOK_QUERY_TYPE_FIELD_TEST;
+ ret->query.field_test.field = field;
+ ret->query.field_test.test = test;
+ ret->query.field_test.value = g_strdup (value);
+
+ return ret;
+}
+
+EBookQuery *
+e_book_query_field_exists (EContactField field)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+
+ ret->type = E_BOOK_QUERY_TYPE_FIELD_EXISTS;
+ ret->query.exist.field = field;
+
+ return ret;
+}
+
+EBookQuery *
+e_book_query_any_field_contains (const char *value)
+{
+ EBookQuery *ret = g_new0 (EBookQuery, 1);
+
+ ret->type = E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS;
+ ret->query.any_field_contains.value = g_strdup (value);
+
+ return ret;
+}
+
+void
+e_book_query_unref (EBookQuery *q)
+{
+ int i;
+
+ if (q->ref_count--)
+ return;
+
+ switch (q->type) {
+ case E_BOOK_QUERY_TYPE_AND:
+ case E_BOOK_QUERY_TYPE_OR:
+ for (i = 0; i < q->query.andor.nqs; i++)
+ e_book_query_unref (q->query.andor.qs[i]);
+ g_free (q->query.andor.qs);
+ break;
+
+ case E_BOOK_QUERY_TYPE_NOT:
+ e_book_query_unref (q->query.not.q);
+ break;
+
+ case E_BOOK_QUERY_TYPE_FIELD_TEST:
+ g_free (q->query.field_test.value);
+ break;
+
+ case E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS:
+ g_free (q->query.any_field_contains.value);
+ break;
+
+ default:
+ break;
+ }
+
+ g_free (q);
+}
+
+void
+e_book_query_ref (EBookQuery *q)
+{
+ q->ref_count++;
+}
+
+static ESExpResult *
+func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+ EBookQuery **qs;
+
+ if (argc > 0) {
+ int i;
+
+ qs = g_new0(EBookQuery*, argc);
+
+ for (i = 0; i < argc; i ++) {
+ GList *list_head = *list;
+ if (!list_head)
+ break;
+ qs[i] = list_head->data;
+ *list = g_list_remove_link(*list, list_head);
+ g_list_free_1(list_head);
+ }
+
+ *list = g_list_prepend(*list,
+ e_book_query_and (argc, qs, TRUE));
+
+ g_free (qs);
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_or(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+ EBookQuery **qs;
+
+ if (argc > 0) {
+ int i;
+
+ qs = g_new0(EBookQuery*, argc);
+
+ for (i = 0; i < argc; i ++) {
+ GList *list_head = *list;
+ if (!list_head)
+ break;
+ qs[i] = list_head->data;
+ *list = g_list_remove_link(*list, list_head);
+ g_list_free_1(list_head);
+ }
+
+ *list = g_list_prepend(*list,
+ e_book_query_or (argc, qs, TRUE));
+
+ g_free (qs);
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+
+ /* just replace the head of the list with the NOT of it. */
+ if (argc > 0) {
+ EBookQuery *term = (*list)->data;
+ (*list)->data = e_book_query_not (term, TRUE);
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+
+ if (argc == 2
+ && argv[0]->type == ESEXP_RES_STRING
+ && argv[1]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+ char *str = argv[1]->value.string;
+
+ if (!strcmp (propname, "x-evolution-any-field")) {
+ *list = g_list_prepend (*list, e_book_query_any_field_contains (str));
+ }
+ else {
+ EContactField field = e_contact_field_id (propname);
+
+ if (field)
+ *list = g_list_prepend (*list, e_book_query_field_test (field,
+ E_BOOK_QUERY_CONTAINS,
+ str));
+ }
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+
+ if (argc == 2
+ && argv[0]->type == ESEXP_RES_STRING
+ && argv[1]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+ char *str = argv[1]->value.string;
+ EContactField field = e_contact_field_id (propname);
+
+ if (field)
+ *list = g_list_prepend (*list, e_book_query_field_test (field,
+ E_BOOK_QUERY_IS,
+ str));
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+
+ if (argc == 2
+ && argv[0]->type == ESEXP_RES_STRING
+ && argv[1]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+ char *str = argv[1]->value.string;
+ EContactField field = e_contact_field_id (propname);
+
+ if (field)
+ *list = g_list_prepend (*list, e_book_query_field_test (field,
+ E_BOOK_QUERY_BEGINS_WITH,
+ str));
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+static ESExpResult *
+func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ GList **list = data;
+ ESExpResult *r;
+
+ if (argc == 2
+ && argv[0]->type == ESEXP_RES_STRING
+ && argv[1]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+ char *str = argv[1]->value.string;
+ EContactField field = e_contact_field_id (propname);
+
+ if (field)
+ *list = g_list_prepend (*list, e_book_query_field_test (field,
+ E_BOOK_QUERY_ENDS_WITH,
+ str));
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
+/* 'builtin' functions */
+static struct {
+ char *name;
+ ESExpFunc *func;
+ int type; /* set to 1 if a function can perform shortcut evaluation, or
+ doesn't execute everything, 0 otherwise */
+} symbols[] = {
+ { "and", func_and, 0 },
+ { "or", func_or, 0 },
+ { "not", func_not, 0 },
+ { "contains", func_contains, 0 },
+ { "is", func_is, 0 },
+ { "beginswith", func_beginswith, 0 },
+ { "endswith", func_endswith, 0 },
+};
+
+EBookQuery*
+e_book_query_from_string (const char *query_string)
+{
+ ESExp *sexp;
+ ESExpResult *r;
+ EBookQuery *retval;
+ GList *list = NULL;
+ int i;
+
+ sexp = e_sexp_new();
+
+ for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
+ if (symbols[i].type == 1) {
+ e_sexp_add_ifunction(sexp, 0, symbols[i].name,
+ (ESExpIFunc *)symbols[i].func, &list);
+ } else {
+ e_sexp_add_function(sexp, 0, symbols[i].name,
+ symbols[i].func, &list);
+ }
+ }
+
+ e_sexp_input_text(sexp, query_string, strlen(query_string));
+ e_sexp_parse(sexp);
+
+ r = e_sexp_eval(sexp);
+
+ e_sexp_result_free(sexp, r);
+ e_sexp_unref (sexp);
+
+ if (list) {
+ if (list->next) {
+ g_warning ("conversion to EBookQuery");
+ retval = NULL;
+ g_list_foreach (list, (GFunc)e_book_query_unref, NULL);
+ }
+ else {
+ retval = list->data;
+ }
+ }
+ else {
+ g_warning ("conversion to EBookQuery failed");
+ retval = NULL;
+ }
+
+ g_list_free (list);
+ return retval;
+}
+
+char*
+e_book_query_to_string (EBookQuery *q)
+{
+ GString *str = g_string_new ("(");
+ int i;
+ char *s = NULL;
+
+ switch (q->type) {
+ case E_BOOK_QUERY_TYPE_AND:
+ g_string_append (str, "and ");
+ for (i = 0; i < q->query.andor.nqs; i ++) {
+ s = e_book_query_to_string (q->query.andor.qs[i]);
+ g_string_append (str, s);
+ g_free (s);
+ g_string_append_c (str, ' ');
+ }
+ break;
+ case E_BOOK_QUERY_TYPE_OR:
+ g_string_append (str, "or ");
+ for (i = 0; i < q->query.andor.nqs; i ++) {
+ s = e_book_query_to_string (q->query.andor.qs[i]);
+ g_string_append (str, s);
+ g_free (s);
+ g_string_append_c (str, ' ');
+ }
+ break;
+ case E_BOOK_QUERY_TYPE_NOT:
+ s = e_book_query_to_string (q->query.not.q);
+ g_string_append_printf (str, "not %s", s);
+ g_free (s);
+ break;
+ case E_BOOK_QUERY_TYPE_FIELD_EXISTS:
+ g_string_append_printf (str, "exists \"%s\"", e_contact_field_name (q->query.exist.field));
+ break;
+ case E_BOOK_QUERY_TYPE_FIELD_TEST:
+ switch (q->query.field_test.test) {
+ case E_BOOK_QUERY_IS: s = "is"; break;
+ case E_BOOK_QUERY_CONTAINS: s = "contains"; break;
+ case E_BOOK_QUERY_BEGINS_WITH: s = "beginswith"; break;
+ case E_BOOK_QUERY_ENDS_WITH: s = "endswith"; break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ /* XXX need to escape q->query.field_test.value */
+ g_string_append_printf (str, "%s \"%s\" \"%s\"",
+ s,
+ e_contact_field_name (q->query.field_test.field),
+ q->query.field_test.value);
+ break;
+ case E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS:
+ g_string_append_printf (str, "contains \"x-evolution-any-field\" \"%s\"", q->query.any_field_contains.value);
+ break;
+ }
+
+
+ g_string_append (str, ")");
+
+ return g_string_free (str, FALSE);
+}
diff --git a/addressbook/backend/ebook/e-book-query.h b/addressbook/backend/ebook/e-book-query.h
new file mode 100644
index 0000000000..e36887f6f2
--- /dev/null
+++ b/addressbook/backend/ebook/e-book-query.h
@@ -0,0 +1,49 @@
+
+#ifndef __E_BOOK_QUERY_H__
+#define __E_BOOK_QUERY_H__
+
+#include <ebook/e-contact.h>
+
+G_BEGIN_DECLS
+
+typedef struct EBookQuery EBookQuery;
+
+typedef enum {
+ E_BOOK_QUERY_IS,
+ E_BOOK_QUERY_CONTAINS,
+ E_BOOK_QUERY_BEGINS_WITH,
+ E_BOOK_QUERY_ENDS_WITH,
+
+#if notyet
+ E_BOOK_QUERY_LT,
+ E_BOOK_QUERY_LE,
+ E_BOOK_QUERY_GT,
+ E_BOOK_QUERY_GE,
+ E_BOOK_QUERY_EQ,
+#endif
+} EBookQueryTest;
+
+EBookQuery* e_book_query_from_string (const char *sexp);
+char* e_book_query_to_string (EBookQuery *q);
+
+void e_book_query_ref (EBookQuery *q);
+void e_book_query_unref (EBookQuery *q);
+
+EBookQuery* e_book_query_and (int nqs, EBookQuery **qs, gboolean unref);
+EBookQuery* e_book_query_andv (EBookQuery *q, ...);
+EBookQuery* e_book_query_or (int nqs, EBookQuery **qs, gboolean unref);
+EBookQuery* e_book_query_orv (EBookQuery *q, ...);
+
+EBookQuery* e_book_query_not (EBookQuery *qs, gboolean unref);
+
+EBookQuery* e_book_query_field_exists (EContactField field);
+EBookQuery* e_book_query_field_test (EContactField field,
+ EBookQueryTest test,
+ const char *value);
+
+/* a special any field contains query */
+EBookQuery* e_book_query_any_field_contains (const char *value);
+
+G_END_DECLS
+
+#endif /* __E_BOOK_QUERY_H__ */
diff --git a/addressbook/backend/ebook/e-book-types.h b/addressbook/backend/ebook/e-book-types.h
index b1900e77ed..4ca69bd516 100644
--- a/addressbook/backend/ebook/e-book-types.h
+++ b/addressbook/backend/ebook/e-book-types.h
@@ -16,37 +16,52 @@
G_BEGIN_DECLS
+#define E_BOOK_ERROR e_book_error_quark()
+
+GQuark e_book_error_quark (void) G_GNUC_CONST;
+
typedef enum {
- E_BOOK_STATUS_SUCCESS,
- E_BOOK_STATUS_UNKNOWN,
- E_BOOK_STATUS_REPOSITORY_OFFLINE,
- E_BOOK_STATUS_PERMISSION_DENIED,
- E_BOOK_STATUS_CARD_NOT_FOUND,
- E_BOOK_STATUS_CARD_ID_ALREADY_EXISTS,
- E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED,
- E_BOOK_STATUS_CANCELLED,
- E_BOOK_STATUS_AUTHENTICATION_FAILED,
- E_BOOK_STATUS_AUTHENTICATION_REQUIRED,
- E_BOOK_STATUS_TLS_NOT_AVAILABLE,
- E_BOOK_STATUS_NO_SUCH_BOOK,
- E_BOOK_STATUS_OTHER_ERROR
+ E_BOOK_ERROR_OK,
+ E_BOOK_ERROR_INVALID_ARG,
+ E_BOOK_ERROR_BUSY,
+ E_BOOK_ERROR_REPOSITORY_OFFLINE,
+ E_BOOK_ERROR_NO_SUCH_BOOK,
+ E_BOOK_ERROR_URI_NOT_LOADED,
+ E_BOOK_ERROR_URI_ALREADY_LOADED,
+ E_BOOK_ERROR_PERMISSION_DENIED,
+ E_BOOK_ERROR_CONTACT_NOT_FOUND,
+ E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS,
+ E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED,
+ E_BOOK_ERROR_CANCELLED,
+ E_BOOK_ERROR_COULD_NOT_CANCEL,
+ E_BOOK_ERROR_AUTHENTICATION_FAILED,
+ E_BOOK_ERROR_AUTHENTICATION_REQUIRED,
+ E_BOOK_ERROR_TLS_NOT_AVAILABLE,
+ E_BOOK_ERROR_CORBA_EXCEPTION,
+ E_BOOK_ERROR_OTHER_ERROR
} EBookStatus;
+
typedef enum {
- E_BOOK_VIEW_STATUS_SUCCESS,
+ E_BOOK_VIEW_STATUS_OK,
E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED,
E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED,
- E_BOOK_VIEW_STATUS_INVALID_QUERY,
- E_BOOK_VIEW_STATUS_QUERY_REFUSED,
- E_BOOK_VIEW_STATUS_OTHER_ERROR,
- E_BOOK_VIEW_STATUS_UNKNOWN
+ E_BOOK_VIEW_ERROR_INVALID_QUERY,
+ E_BOOK_VIEW_ERROR_QUERY_REFUSED,
+ E_BOOK_VIEW_ERROR_OTHER_ERROR
} EBookViewStatus;
typedef enum {
- E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS,
- E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED,
- E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR
-} EBookSimpleQueryStatus;
+ E_BOOK_CHANGE_CARD_ADDED,
+ E_BOOK_CHANGE_CARD_DELETED,
+ E_BOOK_CHANGE_CARD_MODIFIED
+} EBookChangeType;
+
+typedef struct {
+ EBookChangeType change_type;
+ char *vcard; /* used in the ADDED/MODIFIED case */
+ char *id; /* used in the DELETED case */
+} EBookChange;
G_END_DECLS
diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c
deleted file mode 100644
index cc00d045f4..0000000000
--- a/addressbook/backend/ebook/e-book-util.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-book-util.c
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#include <config.h>
-#include "e-book-util.h"
-
-#include <string.h>
-#include <glib.h>
-#include <glib-object.h>
-#include <e-util/e-config-listener.h>
-#include "e-card-compare.h"
-
-typedef struct _CommonBookInfo CommonBookInfo;
-struct _CommonBookInfo {
- EBookCommonCallback cb;
- gpointer closure;
-};
-
-char *
-e_book_expand_uri (const char *uri)
-{
- if (!strncmp (uri, "file:", 5)) {
- int length = strlen (uri);
- int offset = 5;
-
- if (!strncmp (uri, "file://", 7))
- offset = 7;
-
- if (length < 3 || strcmp (uri + length - 3, ".db")) {
- /* we assume it's a dir and glom addressbook.db onto the end. */
-
- char *ret_val;
- char *file_name;
-
- file_name = g_build_filename(uri + offset, "addressbook.db", NULL);
- ret_val = g_strdup_printf("file://%s", file_name);
- g_free(file_name);
- return ret_val;
- }
- }
-
- return g_strdup (uri);
-}
-
-static void
-got_uri_book_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- CommonBookInfo *info = (CommonBookInfo *) closure;
-
- if (status == E_BOOK_STATUS_SUCCESS) {
- info->cb (book, info->closure);
- } else {
- if (book)
- g_object_unref (book);
- info->cb (NULL, info->closure);
- }
- g_free (info);
-}
-
-void
-e_book_load_address_book_by_uri (EBook *book, const char *uri, EBookCallback open_response, gpointer closure)
-{
- char *real_uri;
-
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
- g_return_if_fail (open_response != NULL);
-
- real_uri = e_book_expand_uri (uri);
-
- e_book_load_uri (book, real_uri, open_response, closure);
-
- g_free (real_uri);
-}
-
-void
-e_book_use_address_book_by_uri (const char *uri, EBookCommonCallback cb, gpointer closure)
-{
- EBook *book;
- CommonBookInfo *info;
-
- g_return_if_fail (cb != NULL);
-
- info = g_new0 (CommonBookInfo, 1);
- info->cb = cb;
- info->closure = closure;
-
- book = e_book_new ();
- e_book_load_address_book_by_uri (book, uri, got_uri_book_cb, info);
-}
-
-EConfigListener *
-e_book_get_config_database ()
-{
- static EConfigListener *config_db;
-
- if (config_db == NULL)
- config_db = e_config_listener_new ();
-
- return config_db;
-}
-
-static EBook *common_default_book = NULL;
-
-static void
-got_default_book_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- CommonBookInfo *info = (CommonBookInfo *) closure;
-
- if (status == E_BOOK_STATUS_SUCCESS) {
-
- /* We try not to leak in a race condition where the
- default book got loaded twice. */
-
- if (common_default_book) {
- g_object_unref (book);
- book = common_default_book;
- }
-
- info->cb (book, info->closure);
-
- if (common_default_book == NULL) {
- common_default_book = book;
- }
-
- } else {
- if (book)
- g_object_unref (book);
- info->cb (NULL, info->closure);
-
- }
- g_free (info);
-}
-
-void
-e_book_use_default_book (EBookCommonCallback cb, gpointer closure)
-{
- EBook *book;
- CommonBookInfo *info;
-
- g_return_if_fail (cb != NULL);
-
- if (common_default_book != NULL) {
- cb (common_default_book, closure);
- return;
- }
-
- info = g_new0 (CommonBookInfo, 1);
- info->cb = cb;
- info->closure = closure;
-
- book = e_book_new ();
- e_book_load_default_book (book, got_default_book_cb, info);
-}
-
-static char *default_book_uri;
-
-static char*
-get_local_book_uri (void)
-{
- char *filename;
- char *uri;
-
- filename = g_build_filename (g_get_home_dir(),
- "evolution/local/Contacts/addressbook.db",
- NULL);
- uri = g_strdup_printf ("file://%s", filename);
-
- g_free (filename);
-
- return uri;
-}
-
-static void
-set_default_book_uri_local (void)
-{
- g_free (default_book_uri);
-
- default_book_uri = get_local_book_uri ();
-}
-
-static void
-set_default_book_uri (char *val)
-{
- if (default_book_uri)
- g_free (default_book_uri);
-
- if (val) {
- default_book_uri = e_book_expand_uri (val);
- g_free (val);
- }
- else {
- set_default_book_uri_local ();
- }
-}
-
-#define DEFAULT_CONTACTS_URI_PATH "/apps/evolution/shell/default_folders/contacts_uri"
-static void
-default_folder_listener (EConfigListener *cl, const char *key, gpointer data)
-{
- char *val;
-
- if (strcmp (key, DEFAULT_CONTACTS_URI_PATH))
- return;
-
- val = e_config_listener_get_string (cl, DEFAULT_CONTACTS_URI_PATH);
-
- set_default_book_uri (val);
-}
-
-static void
-set_default_book_uri_from_config_db (void)
-{
- char *val;
- EConfigListener* config_db;
-
- config_db = e_book_get_config_database ();
- val = e_config_listener_get_string_with_default (config_db, DEFAULT_CONTACTS_URI_PATH, NULL, NULL);
-
- g_signal_connect (config_db,
- "key_changed",
- G_CALLBACK (default_folder_listener), NULL);
-
- set_default_book_uri (val);
-}
-
-typedef struct {
- gpointer closure;
- EBookCallback open_response;
-} DefaultBookClosure;
-
-static void
-e_book_default_book_open (EBook *book, EBookStatus status, gpointer closure)
-{
- DefaultBookClosure *default_book_closure = closure;
- gpointer user_closure = default_book_closure->closure;
- EBookCallback user_response = default_book_closure->open_response;
-
- g_free (default_book_closure);
-
- /* If there's a transient error, report it to the caller, but
- * if the old default folder has disappeared, fall back to the
- * local contacts folder instead, except when the default
- * folder is also the local folder.
- */
- if (status == E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED ||
- status == E_BOOK_STATUS_NO_SUCH_BOOK) {
- char *local_uri = get_local_book_uri();
- if (strcmp (local_uri, default_book_uri)) {
- set_default_book_uri_local ();
- e_book_load_default_book (book, user_response, user_closure);
- }
- else
- user_response (book, status, user_closure);
- g_free (local_uri);
- } else {
- user_response (book, status, user_closure);
- }
-}
-
-void
-e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure)
-{
- const char *uri;
- DefaultBookClosure *default_book_closure;
-
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
- g_return_if_fail (open_response != NULL);
-
- uri = e_book_get_default_book_uri ();
-
- default_book_closure = g_new (DefaultBookClosure, 1);
-
- default_book_closure->closure = closure;
- default_book_closure->open_response = open_response;
-
- e_book_load_uri (book, uri,
- e_book_default_book_open, default_book_closure);
-
-}
-
-const char *
-e_book_get_default_book_uri ()
-{
- if (!default_book_uri)
- set_default_book_uri_from_config_db ();
-
- return default_book_uri;
-}
-
-/*
- *
- * Simple Query Stuff
- *
- */
-
-typedef struct _SimpleQueryInfo SimpleQueryInfo;
-struct _SimpleQueryInfo {
- guint tag;
- EBook *book;
- gchar *query;
- EBookSimpleQueryCallback cb;
- gpointer closure;
- EBookView *view;
- guint add_tag;
- guint seq_complete_tag;
- GList *cards;
- gboolean cancelled;
-};
-
-static void
-book_add_simple_query (EBook *book, SimpleQueryInfo *info)
-{
- GList *pending = g_object_get_data (G_OBJECT(book), "sq_pending");
- pending = g_list_prepend (pending, info);
- g_object_set_data (G_OBJECT (book), "sq_pending", pending);
-}
-
-static SimpleQueryInfo *
-book_lookup_simple_query (EBook *book, guint tag)
-{
- GList *pending = g_object_get_data (G_OBJECT (book), "sq_pending");
- while (pending) {
- SimpleQueryInfo *sq = pending->data;
- if (sq->tag == tag)
- return sq;
- pending = g_list_next (pending);
- }
- return NULL;
-}
-
-static void
-book_remove_simple_query (EBook *book, SimpleQueryInfo *info)
-{
- GList *pending = g_object_get_data (G_OBJECT (book), "sq_pending");
- GList *i;
-
- for (i=pending; i != NULL; i = g_list_next (i)) {
- if (i->data == info) {
- pending = g_list_remove_link (pending, i);
- g_list_free_1 (i);
- break;
- }
- }
- g_object_set_data (G_OBJECT (book), "sq_pending", pending);
-}
-
-static guint
-book_issue_tag (EBook *book)
-{
- gpointer ptr = g_object_get_data (G_OBJECT (book), "sq_tag");
- guint tag = GPOINTER_TO_UINT (ptr);
- if (tag == 0)
- tag = 1;
- g_object_set_data (G_OBJECT (book), "sq_tag", GUINT_TO_POINTER (tag+1));
- return tag;
-}
-
-static SimpleQueryInfo *
-simple_query_new (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure)
-{
- SimpleQueryInfo *sq = g_new0 (SimpleQueryInfo, 1);
-
- sq->tag = book_issue_tag (book);
- sq->book = book;
- g_object_ref (book);
- sq->query = g_strdup (query);
- sq->cb = cb;
- sq->closure = closure;
- sq->cancelled = FALSE;
-
- /* Automatically add ourselves to the EBook's pending list. */
- book_add_simple_query (book, sq);
-
- return sq;
-}
-
-static void
-simple_query_disconnect (SimpleQueryInfo *sq)
-{
- if (sq->add_tag) {
- g_signal_handler_disconnect (sq->view, sq->add_tag);
- sq->add_tag = 0;
- }
-
- if (sq->seq_complete_tag) {
- g_signal_handler_disconnect (sq->view, sq->seq_complete_tag);
- sq->seq_complete_tag = 0;
- }
-
- if (sq->view) {
- g_object_unref (sq->view);
- sq->view = NULL;
- }
-}
-
-static void
-simple_query_free (SimpleQueryInfo *sq)
-{
- simple_query_disconnect (sq);
-
- /* Remove ourselves from the EBook's pending list. */
- book_remove_simple_query (sq->book, sq);
-
- g_free (sq->query);
-
- if (sq->book)
- g_object_unref (sq->book);
-
- g_list_foreach (sq->cards, (GFunc) g_object_unref, NULL);
- g_list_free (sq->cards);
-
- g_free (sq);
-}
-
-static void
-simple_query_card_added_cb (EBookView *view, const GList *cards, gpointer closure)
-{
- SimpleQueryInfo *sq = closure;
-
- if (sq->cancelled)
- return;
-
- sq->cards = g_list_concat (sq->cards, g_list_copy ((GList *) cards));
- g_list_foreach ((GList *) cards, (GFunc) g_object_ref, NULL);
-}
-
-static void
-simple_query_sequence_complete_cb (EBookView *view, EBookViewStatus status, gpointer closure)
-{
- SimpleQueryInfo *sq = closure;
-
- /* Disconnect signals, so that we don't pick up any changes to the book that occur
- in our callback */
- simple_query_disconnect (sq);
- if (! sq->cancelled)
- sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS, sq->cards, sq->closure);
- simple_query_free (sq);
-}
-
-static void
-simple_query_book_view_cb (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure)
-{
- SimpleQueryInfo *sq = closure;
-
- if (sq->cancelled) {
- simple_query_free (sq);
- return;
- }
-
- if (status != E_BOOK_STATUS_SUCCESS) {
- simple_query_disconnect (sq);
- sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR, NULL, sq->closure);
- simple_query_free (sq);
- return;
- }
-
- sq->view = book_view;
- g_object_ref (book_view);
-
- sq->add_tag = g_signal_connect (sq->view, "card_added",
- G_CALLBACK (simple_query_card_added_cb), sq);
- sq->seq_complete_tag = g_signal_connect (sq->view, "sequence_complete",
- G_CALLBACK (simple_query_sequence_complete_cb), sq);
-}
-
-guint
-e_book_simple_query (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure)
-{
- SimpleQueryInfo *sq;
-
- g_return_val_if_fail (book && E_IS_BOOK (book), 0);
- g_return_val_if_fail (query, 0);
- g_return_val_if_fail (cb, 0);
-
- sq = simple_query_new (book, query, cb, closure);
- e_book_get_book_view (book, (gchar *) query, simple_query_book_view_cb, sq);
-
- return sq->tag;
-}
-
-void
-e_book_simple_query_cancel (EBook *book, guint tag)
-{
- SimpleQueryInfo *sq;
-
- g_return_if_fail (book && E_IS_BOOK (book));
-
- sq = book_lookup_simple_query (book, tag);
-
- if (sq) {
- sq->cancelled = TRUE;
- sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED, NULL, sq->closure);
- } else {
- g_warning ("Simple query tag %d is unknown", tag);
- }
-}
-
-/*
- *
- * Specialized Queries
- *
- */
-
-typedef struct _NameEmailQueryInfo NameEmailQueryInfo;
-struct _NameEmailQueryInfo {
- gchar *name;
- gchar *email;
- EBookSimpleQueryCallback cb;
- gpointer closure;
-};
-
-static void
-name_email_query_info_free (NameEmailQueryInfo *info)
-{
- if (info) {
- g_free (info->name);
- g_free (info->email);
- g_free (info);
- }
-}
-
-static void
-name_and_email_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- NameEmailQueryInfo *info = closure;
- GList *filtered_cards = NULL;
-
- while (cards) {
- ECard *card = E_CARD (cards->data);
- if ((info->name == NULL || e_card_compare_name_to_string (card, info->name) >= E_CARD_MATCH_VAGUE)
- && (info->email == NULL || e_card_email_match_string (card, info->email))) {
- filtered_cards = g_list_append (filtered_cards, card);
- }
- cards = g_list_next (cards);
- }
-
- info->cb (book, status, filtered_cards, info->closure);
-
- g_list_free (filtered_cards);
-
- name_email_query_info_free (info);
-}
-
-guint
-e_book_name_and_email_query (EBook *book,
- const gchar *name,
- const gchar *email,
- EBookSimpleQueryCallback cb,
- gpointer closure)
-{
- NameEmailQueryInfo *info;
- gchar *email_query=NULL, *name_query=NULL, *query;
- guint tag;
-
- g_return_val_if_fail (book && E_IS_BOOK (book), 0);
- g_return_val_if_fail (cb != NULL, 0);
-
- if (name && !*name)
- name = NULL;
- if (email && !*email)
- email = NULL;
-
- if (name == NULL && email == NULL)
- return 0;
-
- /* Build our e-mail query.
- * We only query against the username part of the address, to avoid not matching
- * fred@foo.com and fred@mail.foo.com. While their may be namespace collisions
- * in the usernames of everyone out there, it shouldn't be that bad. (Famous last words.)
- */
- if (email) {
- const gchar *t = email;
- while (*t && *t != '@')
- ++t;
- if (*t == '@') {
- email_query = g_strdup_printf ("(beginswith \"email\" \"%.*s@\")", t-email, email);
-
- } else {
- email_query = g_strdup_printf ("(beginswith \"email\" \"%s\")", email);
- }
- }
-
- /* Build our name query.
- * We only do name-query stuff if we don't have an e-mail address. Our basic assumption
- * is that the username part of the email is good enough to keep the amount of stuff returned
- * in the query relatively small.
- */
- if (name && !email) {
- gchar *name_cpy = g_strdup (name), *qjoined;
- gchar **namev;
- gint i, count=0;
-
- g_strstrip (name_cpy);
- namev = g_strsplit (name_cpy, " ", 0);
- for (i=0; namev[i]; ++i) {
- if (*namev[i]) {
- char *str = namev[i];
-
- namev[i] = g_strdup_printf ("(contains \"file_as\" \"%s\")", namev[i]);
- ++count;
-
- g_free (str);
- }
- }
-
- qjoined = g_strjoinv (" ", namev);
- if (count > 1) {
- name_query = g_strdup_printf ("(or %s)", qjoined);
- } else {
- name_query = qjoined;
- qjoined = NULL;
- }
-
- g_free (name_cpy);
- g_strfreev (namev);
- g_free (qjoined);
- }
-
- /* Assemble our e-mail & name queries */
- if (email_query && name_query) {
- query = g_strdup_printf ("(and %s %s)", email_query, name_query);
- } else if (email_query) {
- query = email_query;
- email_query = NULL;
- } else if (name_query) {
- query = name_query;
- name_query = NULL;
- } else
- return 0;
-
- info = g_new0 (NameEmailQueryInfo, 1);
- info->name = g_strdup (name);
- info->email = g_strdup (email);
- info->cb = cb;
- info->closure = closure;
-
- tag = e_book_simple_query (book, query, name_and_email_cb, info);
-
- g_free (email_query);
- g_free (name_query);
- g_free (query);
-
- return tag;
-}
-
-/*
- * Simple nickname query
- */
-
-typedef struct _NicknameQueryInfo NicknameQueryInfo;
-struct _NicknameQueryInfo {
- gchar *nickname;
- EBookSimpleQueryCallback cb;
- gpointer closure;
-};
-
-static void
-nickname_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- NicknameQueryInfo *info = closure;
-
- if (info->cb)
- info->cb (book, status, cards, info->closure);
-
- g_free (info->nickname);
- g_free (info);
-}
-
-guint
-e_book_nickname_query (EBook *book,
- const char *nickname,
- EBookSimpleQueryCallback cb,
- gpointer closure)
-{
- NicknameQueryInfo *info;
- gchar *query;
- guint retval;
-
- g_return_val_if_fail (E_IS_BOOK (book), 0);
- g_return_val_if_fail (nickname != NULL, 0);
-
- /* The empty-string case shouldn't generate a warning. */
- if (! *nickname)
- return 0;
-
- info = g_new0 (NicknameQueryInfo, 1);
- info->nickname = g_strdup (nickname);
- info->cb = cb;
- info->closure = closure;
-
- query = g_strdup_printf ("(is \"nickname\" \"%s\")", info->nickname);
-
- retval = e_book_simple_query (book, query, nickname_cb, info);
-
- g_free (query);
-
- return retval;
-}
-
-/*
- * Convenience routine to check for addresses in the local address book.
- */
-
-typedef struct _HaveAddressInfo HaveAddressInfo;
-struct _HaveAddressInfo {
- gchar *email;
- EBookHaveAddressCallback cb;
- gpointer closure;
-};
-
-static void
-have_address_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- HaveAddressInfo *info = (HaveAddressInfo *) closure;
-
- info->cb (book,
- info->email,
- cards && (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) ? E_CARD (cards->data) : NULL,
- info->closure);
-
- g_free (info->email);
- g_free (info);
-}
-
-static void
-have_address_book_open_cb (EBook *book, gpointer closure)
-{
- HaveAddressInfo *info = (HaveAddressInfo *) closure;
-
- if (book) {
-
- e_book_name_and_email_query (book, NULL, info->email, have_address_query_cb, info);
-
- } else {
-
- info->cb (NULL, info->email, NULL, info->closure);
-
- g_free (info->email);
- g_free (info);
-
- }
-}
-
-void
-e_book_query_address_default (const gchar *email,
- EBookHaveAddressCallback cb,
- gpointer closure)
-{
- HaveAddressInfo *info;
-
- g_return_if_fail (email != NULL);
- g_return_if_fail (cb != NULL);
-
- info = g_new0 (HaveAddressInfo, 1);
- info->email = g_strdup (email);
- info->cb = cb;
- info->closure = closure;
-
- e_book_use_default_book (have_address_book_open_cb, info);
-}
-
-/* bad place for this i know. */
-int
-e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len)
-{
- gchar *s1 = g_utf8_casefold(str1, len);
- gchar *s2 = g_utf8_casefold(str2, len);
- int rv;
-
- rv = g_utf8_collate (s1, s2);
-
- g_free (s1);
- g_free (s2);
-
- return rv;
-}
-
-int
-e_utf8_casefold_collate (const gchar *str1, const gchar *str2)
-{
- return e_utf8_casefold_collate_len (str1, str2, -1);
-}
-
diff --git a/addressbook/backend/ebook/e-book-util.h b/addressbook/backend/ebook/e-book-util.h
deleted file mode 100644
index 39eb135332..0000000000
--- a/addressbook/backend/ebook/e-book-util.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-book-util.h
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#ifndef __E_BOOK_UTIL_H__
-#define __E_BOOK_UTIL_H__
-
-#include "e-book.h"
-#include "e-util/e-config-listener.h"
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
-
-G_BEGIN_DECLS
-
-/* Callbacks for asynchronous functions. */
-typedef void (*EBookCommonCallback) (EBook *book, gpointer closure);
-typedef void (*EBookSimpleQueryCallback) (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure);
-typedef void (*EBookHaveAddressCallback) (EBook *book, const gchar *addr, ECard *card, gpointer closure);
-
-/* expand file:///foo/foo/ to file:///foo/foo/addressbook.db */
-char *e_book_expand_uri (const char *uri);
-
-void e_book_load_address_book_by_uri (EBook *book,
- const char *uri,
- EBookCallback open_response,
- gpointer closure);
-void e_book_use_address_book_by_uri (const char *uri,
- EBookCommonCallback cb,
- gpointer closure);
-
-void e_book_use_default_book (EBookCommonCallback cb,
- gpointer closure);
-void e_book_load_default_book (EBook *book,
- EBookCallback open_response,
- gpointer closure);
-const char *e_book_get_default_book_uri (void);
-
-/* config database interface. */
-EConfigListener *e_book_get_config_database (void);
-
-/* Simple Query Interface. */
-guint e_book_simple_query (EBook *book,
- const char *query,
- EBookSimpleQueryCallback cb,
- gpointer closure);
-void e_book_simple_query_cancel (EBook *book,
- guint tag);
-
-/* Specialized Name/Email Queries */
-guint e_book_name_and_email_query (EBook *book,
- const char *name,
- const char *email,
- EBookSimpleQueryCallback cb,
- gpointer closure);
-guint e_book_nickname_query (EBook *book,
- const char *nickname,
- EBookSimpleQueryCallback cb,
- gpointer closure);
-
-/* Returns the ECard associated to email in the callback,
- or NULL if no match is found in the default address book. */
-void e_book_query_address_default (const gchar *email,
- EBookHaveAddressCallback cb,
- gpointer closure);
-
-int e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len);
-int e_utf8_casefold_collate (const gchar *str1, const gchar *str2);
-
-G_END_DECLS
-
-#endif /* __E_BOOK_UTIL_H__ */
-
diff --git a/addressbook/backend/ebook/e-book-view-listener.c b/addressbook/backend/ebook/e-book-view-listener.c
index 668c442a9a..3ab2ff2708 100644
--- a/addressbook/backend/ebook/e-book-view-listener.c
+++ b/addressbook/backend/ebook/e-book-view-listener.c
@@ -13,13 +13,13 @@
#include <bonobo/bonobo-main.h>
#include "e-book-view-listener.h"
#include "e-book-view.h"
-#include "e-card.h"
+#include "e-contact.h"
#include "e-book-marshal.h"
-static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_BookViewListener_CallStatus status);
+static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_CallStatus status);
enum {
- RESPONSES_QUEUED,
+ RESPONSE,
LAST_SIGNAL
};
@@ -28,36 +28,9 @@ static guint e_book_view_listener_signals [LAST_SIGNAL];
static BonoboObjectClass *parent_class;
struct _EBookViewListenerPrivate {
- GList *response_queue;
- gint timeout_id;
-
- guint timeout_lock : 1;
guint stopped : 1;
};
-static gboolean
-e_book_view_listener_check_queue (EBookViewListener *listener)
-{
- if (listener->priv->timeout_lock)
- return TRUE;
-
- listener->priv->timeout_lock = TRUE;
-
- if (listener->priv->response_queue != NULL && !listener->priv->stopped) {
- g_signal_emit (listener, e_book_view_listener_signals [RESPONSES_QUEUED], 0);
- }
-
- if (listener->priv->response_queue == NULL || listener->priv->stopped) {
- listener->priv->timeout_id = 0;
- listener->priv->timeout_lock = FALSE;
- bonobo_object_unref (BONOBO_OBJECT (listener));
- return FALSE;
- }
-
- listener->priv->timeout_lock = FALSE;
- return TRUE;
-}
-
static void
e_book_view_listener_queue_response (EBookViewListener *listener,
EBookViewListenerResponse *response)
@@ -69,45 +42,14 @@ e_book_view_listener_queue_response (EBookViewListener *listener,
/* Free response and return */
g_list_foreach (response->ids, (GFunc)g_free, NULL);
g_list_free (response->ids);
- g_list_foreach (response->cards, (GFunc) g_object_unref, NULL);
- g_list_free (response->cards);
+ g_list_foreach (response->contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (response->contacts);
g_free (response->message);
g_free (response);
return;
}
- /* a slight optimization for huge ldap queries. if there's an
- existing Add response on the end of the queue, and we're an
- Add response, we just glom the two lists of cards
- together */
- if (response->op == CardAddedEvent) {
- GList *last = g_list_last (listener->priv->response_queue);
- EBookViewListenerResponse *last_resp = NULL;
-
- if (last) last_resp = last->data;
-
- if (last_resp && last_resp->op == CardAddedEvent ) {
- response->cards = g_list_concat (last_resp->cards, response->cards);
- g_free (response);
- /* there should already be a timeout since the
- queue isn't empty, so we'll just return
- here */
- return;
- }
- else
- listener->priv->response_queue = g_list_append (last, response);
- }
- else
- listener->priv->response_queue = g_list_append (listener->priv->response_queue, response);
-
- if (listener->priv->timeout_id == 0) {
-
- /* Here, 20 == an arbitrary small number */
- listener->priv->timeout_id = g_timeout_add (20, (GSourceFunc) e_book_view_listener_check_queue, listener);
-
- /* Hold a reference to the listener on behalf of the timeout */
- bonobo_object_ref (BONOBO_OBJECT (listener));
- }
+ g_signal_emit (listener, e_book_view_listener_signals [RESPONSE], 0, response);
}
/* Add, Remove, Modify */
@@ -125,9 +67,6 @@ e_book_view_listener_queue_status_event (EBookViewListener *listener,
resp->op = op;
resp->status = status;
- resp->ids = NULL;
- resp->cards = NULL;
- resp->message = NULL;
e_book_view_listener_queue_response (listener, resp);
}
@@ -136,7 +75,7 @@ e_book_view_listener_queue_status_event (EBookViewListener *listener,
static void
e_book_view_listener_queue_idlist_event (EBookViewListener *listener,
EBookViewListenerOperation op,
- const GNOME_Evolution_Addressbook_CardIdList *ids)
+ const GNOME_Evolution_Addressbook_ContactIdList *ids)
{
EBookViewListenerResponse *resp;
int i;
@@ -147,10 +86,7 @@ e_book_view_listener_queue_idlist_event (EBookViewListener *listener,
resp = g_new0 (EBookViewListenerResponse, 1);
resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->ids = NULL;
- resp->cards = NULL;
- resp->message = NULL;
+ resp->status = E_BOOK_VIEW_STATUS_OK;
for (i = 0; i < ids->_length; i ++) {
resp->ids = g_list_prepend (resp->ids, g_strdup (ids->_buffer[i]));
@@ -163,7 +99,7 @@ e_book_view_listener_queue_idlist_event (EBookViewListener *listener,
static void
e_book_view_listener_queue_sequence_event (EBookViewListener *listener,
EBookViewListenerOperation op,
- const GNOME_Evolution_Addressbook_VCardList *cards)
+ const GNOME_Evolution_Addressbook_VCardList *vcards)
{
EBookViewListenerResponse *resp;
int i;
@@ -174,13 +110,10 @@ e_book_view_listener_queue_sequence_event (EBookViewListener *listener,
resp = g_new0 (EBookViewListenerResponse, 1);
resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->ids = NULL;
- resp->cards = NULL;
- resp->message = NULL;
+ resp->status = E_BOOK_VIEW_STATUS_OK;
- for ( i = 0; i < cards->_length; i++ ) {
- resp->cards = g_list_append(resp->cards, e_card_new(cards->_buffer[i]));
+ for ( i = 0; i < vcards->_length; i++ ) {
+ resp->contacts = g_list_append(resp->contacts, e_contact_new_from_vcard (vcards->_buffer[i]));
}
e_book_view_listener_queue_response (listener, resp);
@@ -200,135 +133,93 @@ e_book_view_listener_queue_message_event (EBookViewListener *listener,
resp = g_new0 (EBookViewListenerResponse, 1);
resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->ids = NULL;
- resp->cards = NULL;
+ resp->status = E_BOOK_VIEW_STATUS_OK;
resp->message = g_strdup(message);
e_book_view_listener_queue_response (listener, resp);
}
static void
-impl_BookViewListener_notify_card_added (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_VCardList *cards,
- CORBA_Environment *ev)
+impl_BookViewListener_notify_contacts_added (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_VCardList *vcards,
+ CORBA_Environment *ev)
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
+ printf ("impl_BookViewListener_notify_contacts_added\n");
+
e_book_view_listener_queue_sequence_event (
- listener, CardAddedEvent, cards);
+ listener, ContactsAddedEvent, vcards);
}
static void
-impl_BookViewListener_notify_cards_removed (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardIdList *ids,
- CORBA_Environment *ev)
+impl_BookViewListener_notify_contacts_removed (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_ContactIdList *ids,
+ CORBA_Environment *ev)
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- e_book_view_listener_queue_idlist_event (listener, CardsRemovedEvent, ids);
+ printf ("impl_BookViewListener_notify_contacts_removed\n");
+
+ e_book_view_listener_queue_idlist_event (listener, ContactsRemovedEvent, ids);
}
static void
-impl_BookViewListener_notify_card_changed (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_VCardList *cards,
- CORBA_Environment *ev)
+impl_BookViewListener_notify_contacts_changed (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_VCardList *vcards,
+ CORBA_Environment *ev)
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
+ printf ("impl_BookViewListener_notify_contacts_changed\n");
+
e_book_view_listener_queue_sequence_event (
- listener, CardModifiedEvent, cards);
+ listener, ContactsModifiedEvent, vcards);
}
static void
impl_BookViewListener_notify_sequence_complete (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status,
+ const GNOME_Evolution_Addressbook_CallStatus status,
CORBA_Environment *ev)
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
+ printf ("impl_BookViewListener_notify_sequence_complete\n");
+
e_book_view_listener_queue_status_event (listener, SequenceCompleteEvent,
e_book_view_listener_convert_status (status));
}
static void
-impl_BookViewListener_notify_status_message (PortableServer_Servant servant,
- const char *message,
- CORBA_Environment *ev)
+impl_BookViewListener_notify_progress (PortableServer_Servant servant,
+ const char *message,
+ const CORBA_short percent,
+ CORBA_Environment *ev)
{
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant));
- e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message);
-}
+ printf ("impl_BookViewListener_notify_progress\n");
-/**
- * e_book_view_listener_check_pending:
- * @listener: the #EBookViewListener
- *
- * Returns: the number of items on the response queue,
- * or -1 if the @listener is isn't an #EBookViewListener.
- */
-int
-e_book_view_listener_check_pending (EBookViewListener *listener)
-{
- g_return_val_if_fail (listener != NULL, -1);
- g_return_val_if_fail (E_IS_BOOK_VIEW_LISTENER (listener), -1);
-
- return g_list_length (listener->priv->response_queue);
-}
-
-/**
- * e_book_view_listener_pop_response:
- * @listener: the #EBookViewListener for which a request is to be popped
- *
- * Returns: an #EBookViewListenerResponse if there are responses on the
- * queue to be returned; %NULL if there aren't, or if the @listener
- * isn't an EBookViewListener.
- */
-EBookViewListenerResponse *
-e_book_view_listener_pop_response (EBookViewListener *listener)
-{
- EBookViewListenerResponse *resp;
- GList *popped;
-
- g_return_val_if_fail (listener != NULL, NULL);
- g_return_val_if_fail (E_IS_BOOK_VIEW_LISTENER (listener), NULL);
-
- if (listener->priv->response_queue == NULL)
- return NULL;
-
- resp = listener->priv->response_queue->data;
-
- popped = listener->priv->response_queue;
- listener->priv->response_queue =
- g_list_remove_link (listener->priv->response_queue,
- listener->priv->response_queue);
- g_list_free_1 (popped);
-
- return resp;
+ e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message);
}
static EBookViewStatus
-e_book_view_listener_convert_status (const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
+e_book_view_listener_convert_status (const GNOME_Evolution_Addressbook_CallStatus status)
{
switch (status) {
- case GNOME_Evolution_Addressbook_BookViewListener_Success:
- return E_BOOK_VIEW_STATUS_SUCCESS;
- case GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded:
+ case GNOME_Evolution_Addressbook_Success:
+ return E_BOOK_VIEW_STATUS_OK;
+ case GNOME_Evolution_Addressbook_SearchTimeLimitExceeded:
return E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED;
- case GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded:
+ case GNOME_Evolution_Addressbook_SearchSizeLimitExceeded:
return E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED;
- case GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery:
- return E_BOOK_VIEW_STATUS_INVALID_QUERY;
- case GNOME_Evolution_Addressbook_BookViewListener_QueryRefused:
- return E_BOOK_VIEW_STATUS_QUERY_REFUSED;
- case GNOME_Evolution_Addressbook_BookViewListener_OtherError:
- return E_BOOK_VIEW_STATUS_OTHER_ERROR;
+ case GNOME_Evolution_Addressbook_InvalidQuery:
+ return E_BOOK_VIEW_ERROR_INVALID_QUERY;
+ case GNOME_Evolution_Addressbook_QueryRefused:
+ return E_BOOK_VIEW_ERROR_QUERY_REFUSED;
+ case GNOME_Evolution_Addressbook_OtherError:
default:
- g_warning ("e_book_view_listener_convert_status: Unknown status "
- "from card server: %d\n", (int) status);
- return E_BOOK_VIEW_STATUS_UNKNOWN;
-
+ return E_BOOK_VIEW_ERROR_OTHER_ERROR;
}
}
@@ -351,7 +242,9 @@ e_book_view_listener_new ()
{
EBookViewListener *listener;
- listener = g_object_new (E_TYPE_BOOK_VIEW_LISTENER, NULL);
+ listener = g_object_new (E_TYPE_BOOK_VIEW_LISTENER,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_ALL_AT_IDLE, NULL),
+ NULL);
e_book_view_listener_construct (listener);
@@ -362,9 +255,6 @@ static void
e_book_view_listener_init (EBookViewListener *listener)
{
listener->priv = g_new0 (EBookViewListenerPrivate, 1);
- listener->priv->response_queue = NULL;
- listener->priv->timeout_id = 0;
- listener->priv->timeout_lock = FALSE;
listener->priv->stopped = FALSE;
}
@@ -381,32 +271,6 @@ e_book_view_listener_dispose (GObject *object)
EBookViewListener *listener = E_BOOK_VIEW_LISTENER (object);
if (listener->priv) {
- GList *l;
- /* Remove our response queue handler: In theory, this
- can never happen since we always hold a reference
- to the listener while the timeout is running. */
- if (listener->priv->timeout_id) {
- g_source_remove (listener->priv->timeout_id);
- }
-
- /* Clear out the queue */
- for (l = listener->priv->response_queue; l != NULL; l = l->next) {
- EBookViewListenerResponse *resp = l->data;
-
- g_list_foreach (resp->ids, (GFunc)g_free, NULL);
- g_list_free (resp->ids);
-
- g_list_foreach(resp->cards, (GFunc) g_object_unref, NULL);
- g_list_free(resp->cards);
- resp->cards = NULL;
-
- g_free (resp->message);
- resp->message = NULL;
-
- g_free (resp);
- }
- g_list_free (listener->priv->response_queue);
-
g_free (listener->priv);
listener->priv = NULL;
}
@@ -423,23 +287,24 @@ e_book_view_listener_class_init (EBookViewListenerClass *klass)
parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT);
- e_book_view_listener_signals [RESPONSES_QUEUED] =
- g_signal_new ("responses_queued",
+ e_book_view_listener_signals [RESPONSE] =
+ g_signal_new ("response",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookViewListenerClass, responses_queued),
+ G_STRUCT_OFFSET (EBookViewListenerClass, response),
NULL, NULL,
- e_book_marshal_NONE__NONE,
- G_TYPE_NONE, 0);
+ e_book_marshal_NONE__POINTER,
+ G_TYPE_NONE,
+ 1, G_TYPE_POINTER);
object_class->dispose = e_book_view_listener_dispose;
epv = &klass->epv;
- epv->notifyCardChanged = impl_BookViewListener_notify_card_changed;
- epv->notifyCardsRemoved = impl_BookViewListener_notify_cards_removed;
- epv->notifyCardAdded = impl_BookViewListener_notify_card_added;
+ epv->notifyContactsChanged = impl_BookViewListener_notify_contacts_changed;
+ epv->notifyContactsRemoved = impl_BookViewListener_notify_contacts_removed;
+ epv->notifyContactsAdded = impl_BookViewListener_notify_contacts_added;
epv->notifySequenceComplete = impl_BookViewListener_notify_sequence_complete;
- epv->notifyStatusMessage = impl_BookViewListener_notify_status_message;
+ epv->notifyProgress = impl_BookViewListener_notify_progress;
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/ebook/e-book-view-listener.h b/addressbook/backend/ebook/e-book-view-listener.h
index fd1c1395a7..a68f25c337 100644
--- a/addressbook/backend/ebook/e-book-view-listener.h
+++ b/addressbook/backend/ebook/e-book-view-listener.h
@@ -29,6 +29,8 @@ typedef struct _EBookViewListener EBookViewListener;
typedef struct _EBookViewListenerClass EBookViewListenerClass;
typedef struct _EBookViewListenerPrivate EBookViewListenerPrivate;
+typedef struct _EBookViewListenerResponse EBookViewListenerResponse;
+
struct _EBookViewListener {
BonoboObject parent;
EBookViewListenerPrivate *priv;
@@ -42,38 +44,44 @@ struct _EBookViewListenerClass {
/*
* Signals
*/
- void (*responses_queued) (void);
+ void (*response) (EBookViewListener *listener, EBookViewListenerResponse *response);
+
+
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
};
typedef enum {
/* Async events */
- CardAddedEvent,
- CardsRemovedEvent,
- CardModifiedEvent,
+ ContactsAddedEvent,
+ ContactsRemovedEvent,
+ ContactsModifiedEvent,
SequenceCompleteEvent,
StatusMessageEvent,
} EBookViewListenerOperation;
-typedef struct {
+struct _EBookViewListenerResponse {
EBookViewListenerOperation op;
/* For SequenceComplete */
EBookViewStatus status;
- /* For CardsRemovedEvent */
+ /* For ContactsRemovedEvent */
GList *ids;
- /* For Card[Added|Modified]Event */
- GList *cards; /* Of type ECard. */
+ /* For Contact[sAdded|Modified]Event */
+ GList *contacts; /* Of type EContact. */
/* For StatusMessageEvent */
char *message;
-} EBookViewListenerResponse;
+};
EBookViewListener *e_book_view_listener_new (void);
-int e_book_view_listener_check_pending (EBookViewListener *listener);
-EBookViewListenerResponse *e_book_view_listener_pop_response (EBookViewListener *listener);
GType e_book_view_listener_get_type (void);
void e_book_view_listener_stop (EBookViewListener *listener);
diff --git a/addressbook/backend/ebook/e-book-view.c b/addressbook/backend/ebook/e-book-view.c
index e1f4b1623c..e8468e35de 100644
--- a/addressbook/backend/ebook/e-book-view.c
+++ b/addressbook/backend/ebook/e-book-view.c
@@ -11,7 +11,6 @@
#include <config.h>
#include "addressbook.h"
-#include "e-card-cursor.h"
#include "e-book-view-listener.h"
#include "e-book-view.h"
#include "e-book.h"
@@ -26,13 +25,13 @@ struct _EBookViewPrivate {
EBookViewListener *listener;
- int responses_queued_id;
+ int response_id;
};
enum {
- CARD_CHANGED,
- CARD_REMOVED,
- CARD_ADDED,
+ CONTACTS_CHANGED,
+ CONTACTS_REMOVED,
+ CONTACTS_ADDED,
SEQUENCE_COMPLETE,
STATUS_MESSAGE,
LAST_SIGNAL
@@ -41,47 +40,32 @@ enum {
static guint e_book_view_signals [LAST_SIGNAL];
static void
-add_book_iterator (gpointer data, gpointer closure)
-{
- ECard *card = E_CARD (data);
- EBook *book = E_BOOK (closure);
-
- e_card_set_book (card, book);
-}
-
-static void
e_book_view_do_added_event (EBookView *book_view,
EBookViewListenerResponse *resp)
{
- if (book_view->priv->book)
- g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book);
-
- g_signal_emit (book_view, e_book_view_signals [CARD_ADDED], 0,
- resp->cards);
+ g_signal_emit (book_view, e_book_view_signals [CONTACTS_ADDED], 0,
+ resp->contacts);
- g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL);
- g_list_free (resp->cards);
+ g_list_foreach (resp->contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (resp->contacts);
}
static void
e_book_view_do_modified_event (EBookView *book_view,
EBookViewListenerResponse *resp)
{
- if (book_view->priv->book)
- g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book);
+ g_signal_emit (book_view, e_book_view_signals [CONTACTS_CHANGED], 0,
+ resp->contacts);
- g_signal_emit (book_view, e_book_view_signals [CARD_CHANGED], 0,
- resp->cards);
-
- g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL);
- g_list_free (resp->cards);
+ g_list_foreach (resp->contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (resp->contacts);
}
static void
e_book_view_do_removed_event (EBookView *book_view,
EBookViewListenerResponse *resp)
{
- g_signal_emit (book_view, e_book_view_signals [CARD_REMOVED], 0,
+ g_signal_emit (book_view, e_book_view_signals [CONTACTS_REMOVED], 0,
resp->ids);
g_list_foreach (resp->ids, (GFunc) g_free, NULL);
@@ -106,27 +90,20 @@ e_book_view_do_status_message_event (EBookView *book_view,
}
-/*
- * Reading notices out of the EBookViewListener's queue.
- */
static void
-e_book_view_check_listener_queue (EBookViewListener *listener, EBookView *book_view)
+e_book_view_handle_response (EBookViewListener *listener, EBookViewListenerResponse *resp, EBookView *book_view)
{
- EBookViewListenerResponse *resp;
-
- resp = e_book_view_listener_pop_response (listener);
-
if (resp == NULL)
return;
switch (resp->op) {
- case CardAddedEvent:
+ case ContactsAddedEvent:
e_book_view_do_added_event (book_view, resp);
break;
- case CardModifiedEvent:
+ case ContactsModifiedEvent:
e_book_view_do_modified_event (book_view, resp);
break;
- case CardsRemovedEvent:
+ case ContactsRemovedEvent:
e_book_view_do_removed_event (book_view, resp);
break;
case SequenceCompleteEvent:
@@ -171,8 +148,8 @@ e_book_view_construct (EBookView *book_view, GNOME_Evolution_Addressbook_BookVie
* Create our local BookListener interface.
*/
book_view->priv->listener = listener;
- book_view->priv->responses_queued_id = g_signal_connect (book_view->priv->listener, "responses_queued",
- G_CALLBACK (e_book_view_check_listener_queue), book_view);
+ book_view->priv->response_id = g_signal_connect (book_view->priv->listener, "response",
+ G_CALLBACK (e_book_view_handle_response), book_view);
bonobo_object_ref(BONOBO_OBJECT(book_view->priv->listener));
@@ -209,6 +186,22 @@ e_book_view_set_book (EBookView *book_view, EBook *book)
}
void
+e_book_view_start (EBookView *book_view)
+{
+ CORBA_Environment ev;
+
+ g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_BookView_start (book_view->priv->corba_book_view, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("corba exception._major = %d\n", ev._major);
+ }
+}
+
+void
e_book_view_stop (EBookView *book_view)
{
g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
@@ -223,7 +216,7 @@ e_book_view_init (EBookView *book_view)
book_view->priv->book = NULL;
book_view->priv->corba_book_view = CORBA_OBJECT_NIL;
book_view->priv->listener = NULL;
- book_view->priv->responses_queued_id = 0;
+ book_view->priv->response_id = 0;
}
static void
@@ -250,9 +243,9 @@ e_book_view_dispose (GObject *object)
}
if (book_view->priv->listener) {
- if (book_view->priv->responses_queued_id)
+ if (book_view->priv->response_id)
g_signal_handler_disconnect(book_view->priv->listener,
- book_view->priv->responses_queued_id);
+ book_view->priv->response_id);
e_book_view_listener_stop (book_view->priv->listener);
bonobo_object_unref (BONOBO_OBJECT(book_view->priv->listener));
}
@@ -271,31 +264,31 @@ e_book_view_class_init (EBookViewClass *klass)
parent_class = g_type_class_ref (G_TYPE_OBJECT);
- e_book_view_signals [CARD_CHANGED] =
- g_signal_new ("card_changed",
+ e_book_view_signals [CONTACTS_CHANGED] =
+ g_signal_new ("contacts_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookViewClass, card_changed),
+ G_STRUCT_OFFSET (EBookViewClass, contacts_changed),
NULL, NULL,
e_book_marshal_NONE__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- e_book_view_signals [CARD_ADDED] =
- g_signal_new ("card_added",
+ e_book_view_signals [CONTACTS_ADDED] =
+ g_signal_new ("contacts_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookViewClass, card_added),
+ G_STRUCT_OFFSET (EBookViewClass, contacts_added),
NULL, NULL,
e_book_marshal_NONE__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- e_book_view_signals [CARD_REMOVED] =
- g_signal_new ("card_removed",
+ e_book_view_signals [CONTACTS_REMOVED] =
+ g_signal_new ("contacts_removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookViewClass, card_removed),
+ G_STRUCT_OFFSET (EBookViewClass, contacts_removed),
NULL, NULL,
e_book_marshal_NONE__POINTER,
G_TYPE_NONE, 1,
diff --git a/addressbook/backend/ebook/e-book-view.h b/addressbook/backend/ebook/e-book-view.h
index bd7a97d1d5..5b9768315b 100644
--- a/addressbook/backend/ebook/e-book-view.h
+++ b/addressbook/backend/ebook/e-book-view.h
@@ -13,7 +13,6 @@
#include <glib.h>
#include <glib-object.h>
-#include <ebook/e-card.h>
#include <ebook/e-book-view-listener.h>
#define E_TYPE_BOOK_VIEW (e_book_view_get_type ())
@@ -42,11 +41,18 @@ struct _EBookViewClass {
/*
* Signals.
*/
- void (* card_changed) (EBookView *book_view, const GList *cards);
- void (* card_removed) (EBookView *book_view, const GList *ids);
- void (* card_added) (EBookView *book_view, const GList *cards);
+ void (* contacts_changed) (EBookView *book_view, const GList *contacts);
+ void (* contacts_removed) (EBookView *book_view, const GList *ids);
+ void (* contacts_added) (EBookView *book_view, const GList *contacts);
void (* sequence_complete) (EBookView *book_view, EBookViewStatus status);
void (* status_message) (EBookView *book_view, const char *message);
+
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
};
/* Creating a new addressbook. */
@@ -56,6 +62,7 @@ GType e_book_view_get_type (void);
void e_book_view_set_book (EBookView *book_view, struct _EBook *book);
+void e_book_view_start (EBookView *book_view);
void e_book_view_stop (EBookView *book_view);
G_END_DECLS
diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c
index 08a0aac995..3883cd4b15 100644
--- a/addressbook/backend/ebook/e-book.c
+++ b/addressbook/backend/ebook/e-book.c
@@ -1,34 +1,86 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * The Evolution addressbook client object.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 1999, 2000, Ximian, Inc.
- */
#include <config.h>
-#include <glib.h>
-#include <glib-object.h>
+
+#include <pthread.h>
+
#include <string.h>
-#include <bonobo-activation/bonobo-activation.h>
-#include "addressbook.h"
-#include "e-card-cursor.h"
-#include "e-book-listener.h"
#include "e-book.h"
+#include "e-vcard.h"
+
+#include <bonobo-activation/bonobo-activation.h>
+
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-main.h>
+
+#include <libgnome/gnome-i18n.h>
+
#include "e-book-marshal.h"
+#include "e-book-listener.h"
+#include "addressbook.h"
#include "e-util/e-component-listener.h"
+#include "e-util/e-msgport.h"
static GObjectClass *parent_class;
#define CARDSERVER_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory"
+#define e_return_error_if_fail(expr,error_code) G_STMT_START{ \
+ if G_LIKELY(expr) { } else \
+ { \
+ g_log (G_LOG_DOMAIN, \
+ G_LOG_LEVEL_CRITICAL, \
+ "file %s: line %d (%s): assertion `%s' failed", \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ #expr); \
+ g_set_error (error, E_BOOK_ERROR, (error_code), \
+ "file %s: line %d (%s): assertion `%s' failed", \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ #expr); \
+ return FALSE; \
+ }; }G_STMT_END
+
+/* XXX we need a better error message here */
+#define E_BOOK_CHECK_STATUS(status,error) G_STMT_START{ \
+ if ((status) == E_BOOK_ERROR_OK) { \
+ return TRUE; \
+ } \
+ else { \
+ g_set_error ((error), E_BOOK_ERROR, (status), "EBookStatus returned %d", (status)); \
+ return FALSE; \
+ } }G_STMT_END
+
+enum {
+ OPEN_PROGRESS,
+ WRITABLE_STATUS,
+ BACKEND_DIED,
+ LAST_SIGNAL
+};
+
+static guint e_book_signals [LAST_SIGNAL];
+
+typedef struct {
+ EMutex *mutex;
+ pthread_cond_t cond;
+ EBookStatus status;
+
+ char *id;
+ GList *list;
+ EContact *contact;
+
+ EBookView *view;
+ EBookViewListener *listener;
+} EBookOp;
+
typedef enum {
- URINotLoaded,
- URILoading,
- URILoaded
+ E_BOOK_URI_NOT_LOADED,
+ E_BOOK_URI_LOADING,
+ E_BOOK_URI_LOADED
} EBookLoadState;
struct _EBookPrivate {
@@ -39,21 +91,20 @@ struct _EBookPrivate {
char *cap;
gboolean cap_queried;
- EBookListener *listener;
+ /* cached writable status */
+ gboolean writable;
+
+ EBookListener *listener;
EComponentListener *comp_listener;
GNOME_Evolution_Addressbook_Book corba_book;
EBookLoadState load_state;
- /*
- * The operation queue. New operations are appended to the
- * end of the queue. When responses come back from the PAS,
- * the op structures are popped off the front of the queue.
- */
- GList *pending_ops;
- guint op_tag;
+ EBookOp *current_op;
+
+ EMutex *mutex;
gchar *uri;
@@ -61,1526 +112,1844 @@ struct _EBookPrivate {
gulong died_signal;
};
-enum {
- OPEN_PROGRESS,
- WRITABLE_STATUS,
- LINK_STATUS,
- BACKEND_DIED,
- LAST_SIGNAL
-};
-
-static guint e_book_signals [LAST_SIGNAL];
+
+/* Error quark */
+GQuark
+e_book_error_quark (void)
+{
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("e-book-error-quark");
-typedef struct {
- guint tag;
- gboolean active;
- gpointer cb;
- gpointer closure;
- EBookViewListener *listener;
-} EBookOp;
+ return q;
+}
-/*
- * Local response queue management.
- */
+
-static void
-e_book_op_free (EBookOp *op)
-{
- if (op->listener) {
- bonobo_object_unref (BONOBO_OBJECT (op->listener));
- op->listener = NULL;
- }
- g_free (op);
-}
+/* EBookOp calls */
-static guint
-e_book_queue_op (EBook *book,
- gpointer cb,
- gpointer closure,
- EBookViewListener *listener)
+static EBookOp*
+e_book_new_op (EBook *book)
{
- EBookOp *op;
+ EBookOp *op = g_new0 (EBookOp, 1);
- op = g_new0 (EBookOp, 1);
- op->tag = book->priv->op_tag++;
- op->active = TRUE;
- op->cb = cb;
- op->closure = closure;
- op->listener = listener;
+ op->mutex = e_mutex_new (E_MUTEX_SIMPLE);
+ pthread_cond_init (&op->cond, 0);
- if (op->listener)
- bonobo_object_ref (BONOBO_OBJECT (op->listener));
+ book->priv->current_op = op;
- book->priv->pending_ops =
- g_list_append (book->priv->pending_ops, op);
+ return op;
+}
- return op->tag;
+static EBookOp*
+e_book_get_op (EBook *book)
+{
+ if (!book->priv->current_op) {
+ g_warning ("unexpected response");
+ return NULL;
+ }
+
+ return book->priv->current_op;
}
-/*
- * Local response queue management.
- */
static void
-e_book_unqueue_op (EBook *book)
+e_book_op_free (EBookOp *op)
{
- EBookOp *op;
- GList *removed;
+ /* XXX more stuff here */
+ pthread_cond_destroy (&op->cond);
+ e_mutex_destroy (op->mutex);
+ g_free (op);
+}
- removed = g_list_last (book->priv->pending_ops);
+static void
+e_book_op_remove (EBook *book,
+ EBookOp *op)
+{
+ if (book->priv->current_op != op)
+ g_warning ("cannot remove op, it's not current");
- if (removed) {
- book->priv->pending_ops = g_list_remove_link (book->priv->pending_ops,
- removed);
- op = removed->data;
- e_book_op_free (op);
- g_list_free_1 (removed);
- book->priv->op_tag--;
- }
+ book->priv->current_op = NULL;
}
-static EBookOp *
-e_book_pop_op (EBook *book)
+static void
+e_book_clear_op (EBook *book,
+ EBookOp *op)
{
- GList *popped;
- EBookOp *op;
+ e_book_op_remove (book, op);
+ e_mutex_unlock (op->mutex);
+ e_book_op_free (op);
+}
- if (book->priv->pending_ops == NULL)
- return NULL;
+
- op = book->priv->pending_ops->data;
+/**
+ * e_book_add_card:
+ * @book: an #EBook
+ * @contact: an #EContact
+ *
+ * adds @contact to @book.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_add_contact (EBook *book,
+ EContact *contact,
+ GError **error)
+{
+ EBookOp *our_op;
+ EBookStatus status;
+ CORBA_Environment ev;
+ char *vcard_str;
- popped = book->priv->pending_ops;
- book->priv->pending_ops =
- g_list_remove_link (book->priv->pending_ops,
- book->priv->pending_ops);
+ printf ("e_book_add_contact\n");
- g_list_free_1 (popped);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
- return op;
-}
+ e_mutex_lock (book->priv->mutex);
-static gboolean
-e_book_cancel_op (EBook *book, guint tag)
-{
- GList *iter;
- gboolean cancelled = FALSE;
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_add_contact called on book before e_book_load_uri"));
+ return FALSE;
+ }
- for (iter = book->priv->pending_ops; iter != NULL && !cancelled; iter = g_list_next (iter)) {
- EBookOp *op = iter->data;
- if (op->tag == tag) {
- op->active = FALSE;
- cancelled = TRUE;
- }
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
-
- return cancelled;
-}
-static void
-e_book_do_response_create_card (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
+ vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- op = e_book_pop_op (book);
+ our_op = e_book_new_op (book);
- if (op == NULL) {
- g_warning ("e_book_do_response_create_card: Cannot find operation "
- "in local op queue!\n");
- return;
- }
+ e_mutex_lock (our_op->mutex);
- if (op->cb)
- ((EBookIdCallback) op->cb) (book, resp->status, resp->id, op->closure);
- g_free (resp->id);
- e_book_op_free (op);
-}
+ e_mutex_unlock (book->priv->mutex);
-static void
-e_book_do_response_generic (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
+ CORBA_exception_init (&ev);
- op = e_book_pop_op (book);
+ /* will eventually end up calling e_book_response_add_contact */
+ GNOME_Evolution_Addressbook_Book_addContact (book->priv->corba_book,
+ (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev);
- if (op == NULL) {
- g_warning ("e_book_do_response_generic: Cannot find operation "
- "in local op queue!\n");
+ g_free (vcard_str);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+
+ e_book_clear_op (book, our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::addContact call"));
+ return FALSE;
}
- if (op->cb)
- ((EBookCallback) op->cb) (book, resp->status, op->closure);
+ CORBA_exception_free (&ev);
- e_book_op_free (op);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ e_contact_set (contact, E_CONTACT_UID, our_op->id);
+ g_free (our_op->id);
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
static void
-e_book_do_response_get_vcard (EBook *book,
- EBookListenerResponse *resp)
+e_book_response_add_contact (EBook *book,
+ EBookStatus status,
+ char *id)
{
EBookOp *op;
- ECard *card;
- op = e_book_pop_op (book);
+ printf ("e_book_response_add_contact\n");
+
+ op = e_book_get_op (book);
if (op == NULL) {
- g_warning ("e_book_do_response_get_vcard: Cannot find operation "
- "in local op queue!\n");
- return;
+ g_warning ("e_book_response_add_contact: Cannot find operation ");
+ return;
}
- if (resp->vcard != NULL) {
- card = e_card_new(resp->vcard);
+ e_mutex_lock (op->mutex);
- if (card != NULL) {
- e_card_set_book (card, book);
- if (op->cb) {
- if (op->active)
- ((EBookCardCallback) op->cb) (book, resp->status, card, op->closure);
- else
- ((EBookCardCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
+ op->status = status;
+ op->id = g_strdup (id);
- g_object_unref(card);
- } else {
- ((EBookCursorCallback) op->cb) (book, resp->status, NULL, op->closure);
- }
- } else {
- ((EBookCardCallback) op->cb) (book, resp->status, NULL, op->closure);
- }
+ pthread_cond_signal (&op->cond);
- g_free (resp->vcard);
- e_book_op_free (op);
+ e_mutex_unlock (op->mutex);
}
-static void
-e_book_do_response_get_cursor (EBook *book,
- EBookListenerResponse *resp)
+
+
+/**
+ * e_book_commit_contact:
+ * @book: an #EBook
+ * @contact: an #EContact
+ *
+ * applies the changes made to @contact to the stored version in
+ * @book.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_commit_contact (EBook *book,
+ EContact *contact,
+ GError **error)
{
+ EBookOp *our_op;
+ EBookStatus status;
CORBA_Environment ev;
- EBookOp *op;
- ECardCursor *cursor;
+ char *vcard_str;
- op = e_book_pop_op (book);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG);
- if (op == NULL) {
- g_warning ("e_book_do_response_get_cursor: Cannot find operation "
- "in local op queue!\n");
- return;
+ e_mutex_lock (book->priv->mutex);
+
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_commit_contact called on book before e_book_load_uri"));
+ return FALSE;
}
- cursor = e_card_cursor_new(resp->cursor);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
+ }
- if (cursor != NULL) {
- if (op->cb) {
- if (op->active)
- ((EBookCursorCallback) op->cb) (book, resp->status, cursor, op->closure);
- else
- ((EBookCursorCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
+ vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- /*
- * Release the remote GNOME_Evolution_Addressbook_Book in the PAS.
- */
- CORBA_exception_init (&ev);
+ our_op = e_book_new_op (book);
- bonobo_object_release_unref (resp->cursor, &ev);
+ e_mutex_lock (our_op->mutex);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_do_response_get_cursor: Exception releasing "
- "remote GNOME_Evolution_Addressbook_CardCursor interface!\n");
- }
+ e_mutex_unlock (book->priv->mutex);
- CORBA_exception_free (&ev);
+ CORBA_exception_init (&ev);
- g_object_unref(cursor);
- } else {
- ((EBookCursorCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- e_book_op_free (op);
-}
+ /* will eventually end up calling _e_book_response_generic */
+ GNOME_Evolution_Addressbook_Book_modifyContact (book->priv->corba_book,
+ (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev);
-static void
-e_book_do_response_get_view (EBook *book,
- EBookListenerResponse *resp)
-{
- CORBA_Environment ev;
- EBookOp *op;
- EBookView *book_view;
+ g_free (vcard_str);
- op = e_book_pop_op (book);
+ if (ev._major != CORBA_NO_EXCEPTION) {
- if (op == NULL) {
- g_warning ("e_book_do_response_get_view: Cannot find operation "
- "in local op queue!\n");
- return;
+ e_book_clear_op (book, our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::modifyContact call"));
+ return FALSE;
}
-
- book_view = e_book_view_new (resp->book_view, op->listener);
-
- if (book_view != NULL) {
- e_book_view_set_book (book_view, book);
-
- /* Only execute the callback if the operation is still flagged as active (i.e. hasn't
- been cancelled. This is mildly wasteful since we unnecessaryily create the
- book_view, etc... but I'm leery of tinkering with the CORBA magic. */
- if (op->cb) {
- if (op->active)
- ((EBookBookViewCallback) op->cb) (book, resp->status, book_view, op->closure);
- else
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- /*
- * Release the remote GNOME_Evolution_Addressbook_Book in the PAS.
- */
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (resp->book_view, &ev);
+ CORBA_exception_free (&ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_do_response_get_view: Exception releasing "
- "remote GNOME_Evolution_Addressbook_BookView interface!\n");
- }
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- CORBA_exception_free (&ev);
+ status = our_op->status;
+ e_contact_set (contact, E_CONTACT_UID, our_op->id);
+ g_free (our_op->id);
- g_object_unref(book_view);
- } else {
- e_book_view_listener_stop (op->listener);
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
+ /* remove the op from the book's hash of operations */
+ e_book_clear_op (book, our_op);
- e_book_op_free (op);
+ E_BOOK_CHECK_STATUS (status, error);
}
-static void
-e_book_do_response_get_changes (EBook *book,
- EBookListenerResponse *resp)
+
+/**
+ * e_book_get_supported_fields:
+ * @book: an #EBook
+ * @fields: a #GList
+ *
+ * queries @book for the list of fields it supports. mostly for use
+ * by the contact editor so it knows what fields to sensitize.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_get_supported_fields (EBook *book,
+ GList **fields,
+ GError **error)
{
+ EBookOp *our_op;
+ EBookStatus status;
CORBA_Environment ev;
- EBookOp *op;
- EBookView *book_view;
- op = e_book_pop_op (book);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (fields, E_BOOK_ERROR_INVALID_ARG);
- if (op == NULL) {
- g_warning ("e_book_do_response_get_changes: Cannot find operation "
- "in local op queue!\n");
- return;
+ e_mutex_lock (book->priv->mutex);
+
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_supported_fields on book before e_book_load_uri"));
+ return FALSE;
}
- book_view = e_book_view_new (resp->book_view, op->listener);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ }
- if (book_view != NULL) {
- e_book_view_set_book (book_view, book);
-
- if (op->cb) {
- if (op->active)
- ((EBookBookViewCallback) op->cb) (book, resp->status, book_view, op->closure);
- else
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
+ our_op = e_book_new_op (book);
- /*
- * Release the remote GNOME_Evolution_Addressbook_BookView in the PAS.
- */
- CORBA_exception_init (&ev);
+ e_mutex_lock (our_op->mutex);
- bonobo_object_release_unref (resp->book_view, &ev);
+ e_mutex_unlock (book->priv->mutex);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_do_response_get_changes: Exception releasing "
- "remote GNOME_Evolution_Addressbook_BookView interface!\n");
- }
+ CORBA_exception_init (&ev);
+
+ /* will eventually end up calling
+ _e_book_response_get_supported_fields */
+ GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+
+ e_book_clear_op (book, our_op);
CORBA_exception_free (&ev);
- g_object_unref(book_view);
- } else {
- e_book_view_listener_stop (op->listener);
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getSupportedFields call"));
+ return FALSE;
}
- e_book_op_free (op);
-}
-static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
-{
- EBook *book = user_data;
+ CORBA_exception_free (&ev);
- book->priv->load_state = URINotLoaded;
- g_signal_emit (book, e_book_signals [BACKEND_DIED], 0);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *fields = our_op->list;
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
static void
-e_book_do_response_open (EBook *book,
- EBookListenerResponse *resp)
+e_book_response_get_supported_fields (EBook *book,
+ EBookStatus status,
+ GList *fields)
{
EBookOp *op;
- if (resp->status == E_BOOK_STATUS_SUCCESS) {
- book->priv->corba_book = resp->book;
- book->priv->load_state = URILoaded;
-
- book->priv->comp_listener = e_component_listener_new (book->priv->corba_book);
- book->priv->died_signal = g_signal_connect (book->priv->comp_listener, "component_died",
- G_CALLBACK (backend_died_cb), book);
- }
-
- op = e_book_pop_op (book);
+ op = e_book_get_op (book);
if (op == NULL) {
- g_warning ("e_book_do_response_open: Cannot find operation "
- "in local op queue!\n");
- return;
+ g_warning ("e_book_response_get_supported_fields: Cannot find operation ");
+ return;
}
- if (op->cb)
- ((EBookCallback) op->cb) (book, resp->status, op->closure);
- e_book_op_free (op);
-}
+ e_mutex_lock (op->mutex);
-static void
-e_book_do_progress_event (EBook *book,
- EBookListenerResponse *resp)
-{
- g_signal_emit (book, e_book_signals [OPEN_PROGRESS], 0,
- resp->msg, resp->percent);
+ op->status = status;
+ op->list = fields;
- g_free (resp->msg);
-}
+ pthread_cond_signal (&op->cond);
-static void
-e_book_do_link_event (EBook *book,
- EBookListenerResponse *resp)
-{
- g_signal_emit (book, e_book_signals [LINK_STATUS], 0,
- resp->connected);
+ e_mutex_unlock (op->mutex);
}
-static void
-e_book_do_writable_event (EBook *book,
- EBookListenerResponse *resp)
+
+/**
+ * e_book_get_supported_auth_methods:
+ * @book: an #EBook
+ * @auth_methods: a #GList
+ *
+ * queries @book for the list of authentication methods it supports.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_get_supported_auth_methods (EBook *book,
+ GList **auth_methods,
+ GError **error)
{
- g_signal_emit (book, e_book_signals [WRITABLE_STATUS], 0,
- resp->writable);
-}
+ EBookOp *our_op;
+ EBookStatus status;
+ CORBA_Environment ev;
-static void
-e_book_do_response_get_supported_fields (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (auth_methods, E_BOOK_ERROR_INVALID_ARG);
- op = e_book_pop_op (book);
+ e_mutex_lock (book->priv->mutex);
- if (op == NULL) {
- g_warning ("e_book_do_response_get_supported_fields: Cannot find operation "
- "in local op queue!\n");
- return;
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_supported_auth_methods on book before e_book_load_uri"));
+ return FALSE;
}
- if (op->cb) {
- if (op->active)
- ((EBookFieldsCallback) op->cb) (book, resp->status, resp->list, op->closure);
- else
- ((EBookFieldsCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
- g_object_unref(resp->list);
+ our_op = e_book_new_op (book);
- e_book_op_free (op);
-}
+ e_mutex_lock (our_op->mutex);
-static void
-e_book_do_response_get_supported_auth_methods (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
+ e_mutex_unlock (book->priv->mutex);
- op = e_book_pop_op (book);
+ CORBA_exception_init (&ev);
- if (op == NULL) {
- g_warning ("e_book_do_response_get_supported_auth_methods: Cannot find operation "
- "in local op queue!\n");
- return;
- }
+ /* will eventually end up calling
+ e_book_response_get_supported_fields */
+ GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods(book->priv->corba_book, &ev);
- if (op->cb) {
- if (op->active)
- ((EBookAuthMethodsCallback) op->cb) (book, resp->status, resp->list, op->closure);
- else
- ((EBookAuthMethodsCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+
+ e_book_clear_op (book, our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getSupportedAuthMethods call"));
+ return FALSE;
}
- g_object_unref(resp->list);
- e_book_op_free (op);
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *auth_methods = our_op->list;
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
-/*
- * Reading notices out of the EBookListener's queue.
- */
static void
-e_book_check_listener_queue (EBookListener *listener, EBook *book)
+e_book_response_get_supported_auth_methods (EBook *book,
+ EBookStatus status,
+ GList *auth_methods)
{
- EBookListenerResponse *resp;
+ EBookOp *op;
- resp = e_book_listener_pop_response (listener);
+ op = e_book_get_op (book);
- if (resp == NULL)
- return;
+ if (op == NULL) {
+ g_warning ("e_book_response_get_supported_auth_methods: Cannot find operation ");
+ return;
+ }
- switch (resp->op) {
- case CreateCardResponse:
- e_book_do_response_create_card (book, resp);
- break;
- case RemoveCardResponse:
- case ModifyCardResponse:
- case AuthenticationResponse:
- e_book_do_response_generic (book, resp);
- break;
- case GetCardResponse:
- e_book_do_response_get_vcard (book, resp);
- break;
- case GetCursorResponse:
- e_book_do_response_get_cursor (book, resp);
- break;
- case GetBookViewResponse:
- e_book_do_response_get_view(book, resp);
- break;
- case GetChangesResponse:
- e_book_do_response_get_changes(book, resp);
- break;
- case OpenBookResponse:
- e_book_do_response_open (book, resp);
- break;
- case GetSupportedFieldsResponse:
- e_book_do_response_get_supported_fields (book, resp);
- break;
- case GetSupportedAuthMethodsResponse:
- e_book_do_response_get_supported_auth_methods (book, resp);
- break;
+ e_mutex_lock (op->mutex);
- case OpenProgressEvent:
- e_book_do_progress_event (book, resp);
- break;
- case LinkStatusEvent:
- e_book_do_link_event (book, resp);
- break;
- case WritableStatusEvent:
- e_book_do_writable_event (book, resp);
- break;
- default:
- g_error ("EBook: Unknown operation %d in listener queue!\n",
- resp->op);
- }
+ op->status = status;
+ op->list = auth_methods;
- g_free (resp);
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
+
+
/**
- * e_book_load_uri:
- */
+ * e_book_authenticate_user:
+ * @book: an #EBook
+ * @user: a string
+ * @passwd: a string
+ * @auth_method: a string
+ *
+ * authenticates @user with @passwd, using the auth method
+ * @auth_method. @auth_method must be one of the authentication
+ * methods returned using e_book_get_supported_auth_methods.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_authenticate_user (EBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method,
+ GError **error)
+{
+ EBookOp *our_op;
+ EBookStatus status;
+ CORBA_Environment ev;
-typedef struct {
- char *uri;
- EBookCallback open_response;
- gpointer closure;
-} EBookLoadURIData;
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (user, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (passwd, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (auth_method, E_BOOK_ERROR_INVALID_ARG);
-static void e_book_load_uri_from_factory (EBook *book,
- GNOME_Evolution_Addressbook_BookFactory factory,
- EBookLoadURIData *load_uri_data);
+ e_mutex_lock (book->priv->mutex);
-static void
-e_book_load_uri_step (EBook *book, EBookStatus status, EBookLoadURIData *data)
-{
- /* iterate to the next possible CardFactory, or fail
- if it's the last one */
- book->priv->iter = book->priv->iter->next;
- if (book->priv->iter) {
- GNOME_Evolution_Addressbook_BookFactory factory = book->priv->iter->data;
- e_book_load_uri_from_factory (book, factory, data);
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_authenticate_user on book before e_book_load_uri"));
+ return FALSE;
}
- else {
- EBookCallback cb = data->open_response;
- gpointer closure = data->closure;
-
- /* reset the load_state to NotLoaded so people can
- attempt another load_uri on the book. */
- book->priv->load_state = URINotLoaded;
- g_free (data);
-
- cb (book, status, closure);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
-}
-
-static void
-e_book_load_uri_open_cb (EBook *book, EBookStatus status, EBookLoadURIData *data)
-{
- if (status == E_BOOK_STATUS_SUCCESS) {
- EBookCallback cb = data->open_response;
- gpointer closure = data->closure;
- g_free (data);
+ our_op = e_book_new_op (book);
- cb (book, status, closure);
- }
- else {
- e_book_load_uri_step (book, status, data);
- }
-}
+ e_mutex_lock (our_op->mutex);
-static void
-e_book_load_uri_from_factory (EBook *book,
- GNOME_Evolution_Addressbook_BookFactory factory,
- EBookLoadURIData *load_uri_data)
-{
- CORBA_Environment ev;
+ e_mutex_unlock (book->priv->mutex);
CORBA_exception_init (&ev);
- e_book_queue_op (book, e_book_load_uri_open_cb, load_uri_data, NULL);
-
- GNOME_Evolution_Addressbook_BookFactory_openBook (
- factory, book->priv->uri,
- bonobo_object_corba_objref (BONOBO_OBJECT (book->priv->listener)),
- &ev);
+ /* will eventually end up calling
+ e_book_response_generic */
+ GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book,
+ user, passwd,
+ auth_method,
+ &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_load_uri: CORBA exception while opening addressbook!\n");
- e_book_unqueue_op (book);
+
+ e_book_clear_op (book, our_op);
+
CORBA_exception_free (&ev);
- e_book_load_uri_step (book, E_BOOK_STATUS_OTHER_ERROR, load_uri_data);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::authenticateUser call"));
+ return FALSE;
}
CORBA_exception_free (&ev);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
+
-static gboolean
-activate_factories_for_uri (EBook *book, const char *uri)
+/**
+ * e_book_get_contact:
+ * @book: an #EBook
+ * @id: a string
+ * @contact: an #EContact
+ *
+ * Fills in @contact with the contents of the vcard in @book
+ * corresponding to @id.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_get_contact (EBook *book,
+ const char *id,
+ EContact **contact,
+ GError **error)
{
+ EBookOp *our_op;
+ EBookStatus status;
CORBA_Environment ev;
- Bonobo_ServerInfoList *info_list = NULL;
- int i;
- char *protocol, *query, *colon;
- gboolean retval = FALSE;
- colon = strchr (uri, ':');
- if (!colon) {
- g_warning ("e_book_load_uri: Unable to determine protocol in the URI\n");
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (contact, E_BOOK_ERROR_INVALID_ARG);
+
+ e_mutex_lock (book->priv->mutex);
+
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_contact on book before e_book_load_uri"));
return FALSE;
}
- protocol = g_strndup (uri, colon-uri);
- query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/BookFactory:1.0')"
- " AND addressbook:supported_protocols.has ('%s')", protocol
- );
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
+ }
+
+ our_op = e_book_new_op (book);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (book->priv->mutex);
CORBA_exception_init (&ev);
-
- info_list = bonobo_activation_query (query, NULL, &ev);
+
+ /* will eventually end up calling e_book_response_generic */
+ GNOME_Evolution_Addressbook_Book_getContact (book->priv->corba_book,
+ (const GNOME_Evolution_Addressbook_VCard) id, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Eeek! Cannot perform bonobo-activation query for book factories.");
- CORBA_exception_free (&ev);
- goto shutdown;
- }
- if (info_list->_length == 0) {
- g_warning ("Can't find installed BookFactory that handles protocol '%s'.", protocol);
+ e_book_clear_op (book, our_op);
+
CORBA_exception_free (&ev);
- goto shutdown;
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getContact call"));
+ return FALSE;
}
CORBA_exception_free (&ev);
- for (i = 0; i < info_list->_length; i ++) {
- const Bonobo_ServerInfo *info;
- GNOME_Evolution_Addressbook_BookFactory factory;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- info = info_list->_buffer + i;
+ status = our_op->status;
+ *contact = our_op->contact;
- factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
+ e_book_clear_op (book, our_op);
- if (factory == CORBA_OBJECT_NIL)
- g_warning ("e_book_construct: Could not obtain a handle "
- "to the Personal Addressbook Server with IID `%s'\n", info->iid);
- else
- book->priv->book_factories = g_list_append (book->priv->book_factories,
- factory);
- }
+ E_BOOK_CHECK_STATUS (status, error);
+}
- if (!book->priv->book_factories) {
- g_warning ("Couldn't activate any book factories.");
- goto shutdown;
+static void
+e_book_response_get_contact (EBook *book,
+ EBookStatus status,
+ EContact *contact)
+{
+ EBookOp *op;
+
+ printf ("e_book_response_get_contact\n");
+
+ op = e_book_get_op (book);
+
+ if (op == NULL) {
+ g_warning ("e_book_response_get_contact: Cannot find operation ");
+ return;
}
- retval = TRUE;
+ e_mutex_lock (op->mutex);
- shutdown:
- if (info_list)
- CORBA_free (info_list);
- g_free (query);
- g_free (protocol);
+ op->status = status;
+ op->contact = contact;
- return retval;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-void
-e_book_load_uri (EBook *book,
- const char *uri,
- EBookCallback open_response,
- gpointer closure)
+
+/**
+ * e_book_remove_contact:
+ * @book: an #EBook
+ * @id: a string
+ *
+ * Removes the contact with id @id from @book.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_remove_contact (EBook *book,
+ const char *id,
+ GError **error)
{
- EBookLoadURIData *load_uri_data;
- GNOME_Evolution_Addressbook_BookFactory factory;
+ GList *list;
+ gboolean rv;
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
- g_return_if_fail (uri != NULL);
- g_return_if_fail (open_response != NULL);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG);
- if (book->priv->load_state != URINotLoaded) {
- g_warning ("e_book_load_uri: Attempted to load a URI "
- "on a book which already has a URI loaded!\n");
- open_response (book, E_BOOK_STATUS_OTHER_ERROR, closure); /* XXX need a new status code here */
- return;
- }
+ e_mutex_lock (book->priv->mutex);
- /* try to find a list of factories that can handle the protocol */
- if (!activate_factories_for_uri (book, uri)) {
- open_response (book, E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED, closure);
- return;
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_remove_contact on book before e_book_load_uri"));
+ return FALSE;
}
-
- g_free (book->priv->uri);
- book->priv->uri = g_strdup (uri);
- /*
- * Create our local BookListener interface.
- */
- book->priv->listener = e_book_listener_new ();
- if (book->priv->listener == NULL) {
- g_warning ("e_book_load_uri: Could not create EBookListener!\n");
- open_response (NULL, E_BOOK_STATUS_OTHER_ERROR, closure); /* XXX need a new status code here */
- return;
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
- book->priv->listener_signal = g_signal_connect (book->priv->listener, "responses_queued",
- G_CALLBACK (e_book_check_listener_queue), book);
+ e_mutex_lock (book->priv->mutex);
- load_uri_data = g_new (EBookLoadURIData, 1);
- load_uri_data->open_response = open_response;
- load_uri_data->closure = closure;
+ list = g_list_append (NULL, (char*)id);
- /* initialize the iterator, and load from the first one*/
- book->priv->iter = book->priv->book_factories;
+ rv = e_book_remove_contacts (book, list, error);
- factory = book->priv->iter->data;
-
- e_book_load_uri_from_factory (book, factory, load_uri_data);
-
- book->priv->load_state = URILoading;
+ return rv;
}
/**
- * e_book_unload_uri:
- */
-void
-e_book_unload_uri (EBook *book)
+ * e_book_remove_contacts:
+ * @book: an #EBook
+ * @ids: an #GList of const char *id's
+ *
+ * Removes the contacts with ids from the list @ids from @book. This is
+ * always more efficient than calling e_book_remove_contact_by_id if you
+ * have more than one id to remove, as some backends can implement it
+ * as a batch request.
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_remove_contacts (EBook *book,
+ GList *ids,
+ GError **error)
{
+ GNOME_Evolution_Addressbook_ContactIdList idlist;
CORBA_Environment ev;
+ GList *iter;
+ int num_ids, i;
+ EBookOp *our_op;
+ EBookStatus status;
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (ids, E_BOOK_ERROR_INVALID_ARG);
- /*
- * FIXME: Make sure this works if the URI is still being
- * loaded.
- */
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_unload_uri: No URI is loaded!\n");
- return;
- }
+ e_mutex_lock (book->priv->mutex);
- /*
- * Release the remote GNOME_Evolution_Addressbook_Book in the PAS.
- */
- CORBA_exception_init (&ev);
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_remove_contacts on book before e_book_load_uri"));
+ return FALSE;
+ }
- bonobo_object_release_unref (book->priv->corba_book, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_unload_uri: Exception releasing "
- "remote book interface!\n");
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
- CORBA_exception_free (&ev);
+ our_op = e_book_new_op (book);
- e_book_listener_stop (book->priv->listener);
- bonobo_object_unref (BONOBO_OBJECT (book->priv->listener));
+ e_mutex_lock (our_op->mutex);
- book->priv->listener = NULL;
- book->priv->load_state = URINotLoaded;
-}
+ e_mutex_unlock (book->priv->mutex);
-const char *
-e_book_get_uri (EBook *book)
-{
- g_return_val_if_fail (book && E_IS_BOOK (book), NULL);
-
- return book->priv->uri;
-}
-
-char *
-e_book_get_static_capabilities (EBook *book)
-{
- if (!book->priv->cap_queried) {
- CORBA_Environment ev;
- char *temp;
+ CORBA_exception_init (&ev);
- CORBA_exception_init (&ev);
+ num_ids = g_list_length (ids);
+ idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_allocbuf (num_ids);
+ idlist._maximum = num_ids;
+ idlist._length = num_ids;
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_unload_uri: No URI is loaded!\n");
- return g_strdup("");
- }
+ for (iter = ids, i = 0; iter; iter = iter->next)
+ idlist._buffer[i++] = CORBA_string_dup (iter->data);
- temp = GNOME_Evolution_Addressbook_Book_getStaticCapabilities(book->priv->corba_book, &ev);
+ /* will eventually end up calling e_book_response_generic */
+ GNOME_Evolution_Addressbook_Book_removeContacts (book->priv->corba_book, &idlist, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_static_capabilities: Exception "
- "during get_static_capabilities!\n");
- CORBA_exception_free (&ev);
- return g_strdup("");
- }
+ CORBA_free(idlist._buffer);
- book->priv->cap = g_strdup(temp);
- book->priv->cap_queried = TRUE;
+ if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_free(temp);
+ e_book_clear_op (book, our_op);
CORBA_exception_free (&ev);
- }
- return g_strdup (book->priv->cap);
-}
-
-gboolean
-e_book_check_static_capability (EBook *book, const char *cap)
-{
- gboolean rv = FALSE;
- char *caps = e_book_get_static_capabilities (book);
- if (!caps)
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::removeContacts call"));
return FALSE;
+ }
+
+ CORBA_exception_free (&ev);
- /* XXX this is an inexact test but it works for our use */
- if (strstr (caps, cap))
- rv = TRUE;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- g_free (caps);
+ status = our_op->status;
- return rv;
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
-guint
-e_book_get_supported_fields (EBook *book,
- EBookFieldsCallback cb,
- gpointer closure)
+
+/**
+ * e_book_get_book_view:
+ * @book: an #EBook
+ * @query: an #EBookQuery
+ * @requested_fields a #GList containing the names of fields to return, or NULL for all
+ * @max_results the maximum number of contacts to show (or 0 for all)
+ *
+ * need docs here..
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_get_book_view (EBook *book,
+ EBookQuery *query,
+ GList *requested_fields,
+ int max_results,
+ EBookView **book_view,
+ GError **error)
{
+ GNOME_Evolution_Addressbook_stringlist stringlist;
CORBA_Environment ev;
- guint tag;
+ EBookOp *our_op;
+ EBookStatus status;
+ int num_fields, i;
+ GList *iter;
+ char *query_string;
- CORBA_exception_init (&ev);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (book_view, E_BOOK_ERROR_INVALID_ARG);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_unload_uri: No URI is loaded!\n");
- return 0;
- }
+ e_mutex_lock (book->priv->mutex);
- tag = e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, &ev);
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_book_view on book before e_book_load_uri"));
+ return FALSE;
+ }
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_supported_fields: Exception "
- "during get_supported_fields!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
- CORBA_exception_free (&ev);
+ our_op = e_book_new_op (book);
- return tag;
-}
+ e_mutex_lock (our_op->mutex);
-guint
-e_book_get_supported_auth_methods (EBook *book,
- EBookAuthMethodsCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
- guint tag;
+ e_mutex_unlock (book->priv->mutex);
CORBA_exception_init (&ev);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_unload_uri: No URI is loaded!\n");
- return 0;
- }
+ our_op->listener = e_book_view_listener_new();
- tag = e_book_queue_op (book, cb, closure, NULL);
+ num_fields = g_list_length (requested_fields);
- GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods(book->priv->corba_book, &ev);
+ stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
+ stringlist._maximum = num_fields;
+ stringlist._length = num_fields;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_supported_auth_methods: Exception "
- "during get_supported_auth_methods!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
+ for (i = 0, iter = requested_fields; iter; iter = iter->next, i ++) {
+ stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data);
}
- CORBA_exception_free (&ev);
+ query_string = e_book_query_to_string (query);
- return tag;
-}
+ /* will eventually end up calling e_book_response_get_book_view */
+ GNOME_Evolution_Addressbook_Book_getBookView (book->priv->corba_book,
+ bonobo_object_corba_objref(BONOBO_OBJECT(our_op->listener)),
+ query_string,
+ &stringlist, max_results, &ev);
-static gboolean
-e_book_construct (EBook *book)
-{
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
+ CORBA_free(stringlist._buffer);
+ g_free (query_string);
- book->priv->book_factories = NULL;
+ if (ev._major != CORBA_NO_EXCEPTION) {
- return TRUE;
-}
+ e_book_clear_op (book, our_op);
-/**
- * e_book_new:
- */
-EBook *
-e_book_new (void)
-{
- EBook *book;
+ CORBA_exception_free (&ev);
- book = g_object_new (E_TYPE_BOOK, NULL);
+ g_warning ("corba exception._major = %d\n", ev._major);
- if (! e_book_construct (book)) {
- g_object_unref (book);
- return NULL;
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getBookView call"));
+ return FALSE;
}
+
+ CORBA_exception_free (&ev);
- return book;
-}
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
-/* User authentication. */
+ status = our_op->status;
+ *book_view = our_op->view;
-void
-e_book_authenticate_user (EBook *book,
- const char *user,
- const char *passwd,
- const char *auth_method,
- EBookCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
+ e_book_clear_op (book, our_op);
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
+ E_BOOK_CHECK_STATUS (status, error);
+}
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_authenticate_user: No URI loaded!\n");
- return;
- }
+static void
+e_book_response_get_book_view (EBook *book,
+ EBookStatus status,
+ GNOME_Evolution_Addressbook_BookView corba_book_view)
+{
- CORBA_exception_init (&ev);
+ EBookOp *op;
- e_book_queue_op (book, cb, closure, NULL);
+ printf ("e_book_response_get_book_view\n");
- GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book,
- user,
- passwd,
- auth_method,
- &ev);
+ op = e_book_get_op (book);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_authenticate_user: Exception authenticating user with the PAS!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return;
+ if (op == NULL) {
+ g_warning ("e_book_response_get_book_view: Cannot find operation ");
+ return;
}
- CORBA_exception_free (&ev);
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->view = e_book_view_new (corba_book_view, op->listener);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-/* Fetching cards */
+
/**
- * e_book_get_card:
- */
-guint
-e_book_get_card (EBook *book,
- const char *id,
- EBookCardCallback cb,
- gpointer closure)
+ * e_book_get_contacts:
+ * @book: an #EBook
+ * @query: an #EBookQuery
+ *
+ * need docs here..
+ *
+ * Return value: a #EBookStatus value.
+ **/
+gboolean
+e_book_get_contacts (EBook *book,
+ EBookQuery *query,
+ GList **contacts,
+ GError **error)
{
CORBA_Environment ev;
- guint tag;
+ EBookOp *our_op;
+ EBookStatus status;
+ char *query_string;
+
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (contacts, E_BOOK_ERROR_INVALID_ARG);
+
+ e_mutex_lock (book->priv->mutex);
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_contacts on book before e_book_load_uri"));
+ return FALSE;
+ }
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_card: No URI loaded!\n");
- return 0;
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
}
+ our_op = e_book_new_op (book);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (book->priv->mutex);
+
CORBA_exception_init (&ev);
- tag = e_book_queue_op (book, cb, closure, NULL);
+ query_string = e_book_query_to_string (query);
- GNOME_Evolution_Addressbook_Book_getVCard (book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) id, &ev);
+ /* will eventually end up calling e_book_response_get_contacts */
+ GNOME_Evolution_Addressbook_Book_getContactList (book->priv->corba_book, query_string, &ev);
+
+ g_free (query_string);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_card: Exception "
- "getting card!\n");
+
+ e_book_clear_op (book, our_op);
+
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
- }
+ g_warning ("corba exception._major = %d\n", ev._major);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getContactList call"));
+ return FALSE;
+ }
+
CORBA_exception_free (&ev);
- return tag;
-}
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
-/* Deleting cards. */
+ status = our_op->status;
+ *contacts = our_op->list;
-/**
- * e_book_remove_card:
- */
-gboolean
-e_book_remove_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure)
-{
- const char *id;
+ e_book_clear_op (book, our_op);
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (card != NULL, FALSE);
- g_return_val_if_fail (E_IS_CARD (card), FALSE);
+ E_BOOK_CHECK_STATUS (status, error);
+}
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_remove_card: No URI loaded!\n");
- return FALSE;
- }
+static void
+e_book_response_get_contacts (EBook *book,
+ EBookStatus status,
+ GList *contact_list)
+{
- id = e_card_get_id (card);
- g_assert (id != NULL);
+ EBookOp *op;
- return e_book_remove_card_by_id (book, id, cb, closure);
-}
+ op = e_book_get_op (book);
-/**
- * e_book_remove_card_by_id:
- */
-gboolean
-e_book_remove_card_by_id (EBook *book,
- const char *id,
- EBookCallback cb,
- gpointer closure)
+ if (op == NULL) {
+ g_warning ("e_book_response_get_contacts: Cannot find operation ");
+ return;
+ }
-{
- GList *list = NULL;
- gboolean rv;
+ e_mutex_lock (op->mutex);
- list = g_list_prepend (list, (char*)id);
-
- rv = e_book_remove_cards (book, list, cb, closure);
+ op->status = status;
+ op->list = contact_list;
- g_list_free (list);
+ pthread_cond_signal (&op->cond);
- return rv;
+ e_mutex_unlock (op->mutex);
}
+
gboolean
-e_book_remove_cards (EBook *book,
- GList *ids,
- EBookCallback cb,
- gpointer closure)
+e_book_get_changes (EBook *book,
+ char *changeid,
+ GList **changes,
+ GError **error)
{
- GNOME_Evolution_Addressbook_CardIdList idlist;
CORBA_Environment ev;
- GList *l;
- int num_ids, i;
+ EBookOp *our_op;
+ EBookStatus status;
+
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (changeid, E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (changes, E_BOOK_ERROR_INVALID_ARG);
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (ids != NULL, FALSE);
+ e_mutex_lock (book->priv->mutex);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_remove_card_by_id: No URI loaded!\n");
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_get_changes on book before e_book_load_uri"));
return FALSE;
}
- CORBA_exception_init (&ev);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
+ }
- e_book_queue_op (book, cb, closure, NULL);
+ our_op = e_book_new_op (book);
- num_ids = g_list_length (ids);
- idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids);
- idlist._maximum = num_ids;
- idlist._length = num_ids;
+ e_mutex_lock (our_op->mutex);
- for (l = ids, i = 0; l; l=l->next, i ++) {
- idlist._buffer[i] = CORBA_string_dup (l->data);
- }
+ e_mutex_unlock (book->priv->mutex);
- GNOME_Evolution_Addressbook_Book_removeCards (book->priv->corba_book, &idlist, &ev);
+ CORBA_exception_init (&ev);
+
+ /* will eventually end up calling e_book_response_get_changes */
+ GNOME_Evolution_Addressbook_Book_getChanges (book->priv->corba_book, changeid, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_remove_card_by_id: CORBA exception "
- "talking to PAS!\n");
+
+ e_book_clear_op (book, our_op);
+
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
+
+ g_warning ("corba exception._major = %d\n", ev._major);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::getChanges call"));
return FALSE;
}
CORBA_exception_free (&ev);
- CORBA_free(idlist._buffer);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- return TRUE;
+ status = our_op->status;
+ *changes = our_op->list;
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
+static void
+e_book_response_get_changes (EBook *book,
+ EBookStatus status,
+ GList *change_list)
+{
+
+ EBookOp *op;
-/* Adding cards. */
+ op = e_book_get_op (book);
-/**
- * e_book_add_card:
- */
-gboolean
-e_book_add_card (EBook *book,
- ECard *card,
- EBookIdCallback cb,
- gpointer closure)
+ if (op == NULL) {
+ g_warning ("e_book_response_get_contacts: Cannot find operation ");
+ return;
+ }
-{
- char *vcard;
- gboolean retval;
+ e_mutex_lock (op->mutex);
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (card != NULL, FALSE);
- g_return_val_if_fail (E_IS_CARD (card), FALSE);
+ op->status = status;
+ op->list = change_list;
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_add_card: No URI loaded!\n");
- return FALSE;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+void
+e_book_free_change_list (GList *change_list)
+{
+ GList *l;
+ for (l = change_list; l; l = l->next) {
+ EBookChange *change = l->data;
+
+ g_free (change->vcard);
+ g_free (change);
}
- vcard = e_card_get_vcard_assume_utf8 (card);
+ g_list_free (change_list);
+}
+
+
- if (vcard == NULL) {
- g_warning ("e_book_add_card: Cannot convert card to VCard string!\n");
- return FALSE;
+static void
+e_book_response_generic (EBook *book,
+ EBookStatus status)
+{
+ EBookOp *op;
+
+ op = e_book_get_op (book);
+
+ if (op == NULL) {
+ g_warning ("e_book_response_generic: Cannot find operation ");
+ return;
}
- retval = e_book_add_vcard (book, vcard, cb, closure);
+ e_mutex_lock (op->mutex);
- g_free (vcard);
+ op->status = status;
- e_card_set_book (card, book);
+ pthread_cond_signal (&op->cond);
- return retval;
+ e_mutex_unlock (op->mutex);
}
/**
- * e_book_add_vcard:
- */
+ * e_book_cancel:
+ * @book: an #EBook
+ *
+ * Used to cancel an already running operation on @book. This
+ * function makes a synchronous CORBA to the backend telling it to
+ * cancel the operation. If the operation wasn't cancellable (either
+ * transiently or permanently) or had already comopleted on the wombat
+ * side, this function will return E_BOOK_STATUS_COULD_NOT_CANCEL, and
+ * the operation will continue uncancelled. If the operation could be
+ * cancelled, this function will return E_BOOK_ERROR_OK, and the
+ * blocked e_book function corresponding to current operation will
+ * return with a status of E_BOOK_STATUS_CANCELLED.
+ *
+ * Return value: a #EBookStatus value.
+ **/
gboolean
-e_book_add_vcard (EBook *book,
- const char *vcard,
- EBookIdCallback cb,
- gpointer closure)
+e_book_cancel (EBook *book,
+ GError **error)
{
+ EBookOp *op;
+ EBookStatus status;
+ gboolean rv;
CORBA_Environment ev;
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (vcard != NULL, FALSE);
+ e_mutex_lock (book->priv->mutex);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_add_vcard: No URI loaded!\n");
+ if (book->priv->current_op == NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL,
+ _("e_book_cancel: there is no current operation"));
return FALSE;
}
- CORBA_exception_init (&ev);
+ op = book->priv->current_op;
+
+ e_mutex_lock (op->mutex);
- e_book_queue_op (book, (EBookCallback) cb, closure, NULL);
+ e_mutex_unlock (book->priv->mutex);
- GNOME_Evolution_Addressbook_Book_addCard (
- book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev);
+ status = GNOME_Evolution_Addressbook_Book_cancelOperation(book->priv->corba_book, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_add_vcard: Exception adding card to PAS!\n");
+
+ e_mutex_unlock (op->mutex);
+
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::cancelOperation call"));
return FALSE;
}
CORBA_exception_free (&ev);
- return TRUE;
-}
-
-/* Modifying cards. */
+ if (status == E_BOOK_ERROR_OK) {
+ op->status = E_BOOK_ERROR_CANCELLED;
-/**
- * e_book_commit_card:
- */
-gboolean
-e_book_commit_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure)
-{
- char *vcard;
- gboolean retval;
-
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (card != NULL, FALSE);
- g_return_val_if_fail (E_IS_CARD (card), FALSE);
+ pthread_cond_signal (&op->cond);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_commit_card: No URI loaded!\n");
- return FALSE;
+ rv = TRUE;
+ }
+ else {
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL,
+ _("e_book_cancel: couldn't cancel"));
+ rv = FALSE;
}
- vcard = e_card_get_vcard_assume_utf8 (card);
+ e_mutex_unlock (op->mutex);
- if (vcard == NULL) {
- g_warning ("e_book_commit_card: Error "
- "getting VCard for card!\n");
- return FALSE;
+ return rv;
+}
+
+static void
+e_book_response_open (EBook *book,
+ EBookStatus status)
+{
+ EBookOp *op;
+
+ op = e_book_get_op (book);
+
+ if (op == NULL) {
+ g_warning ("e_book_response_open: Cannot find operation ");
+ return;
}
- retval = e_book_commit_vcard (book, vcard, cb, closure);
+ e_mutex_lock (op->mutex);
- g_free (vcard);
+ op->status = status;
- e_card_set_book (card, book);
+ pthread_cond_signal (&op->cond);
- return retval;
+ e_mutex_unlock (op->mutex);
}
-/**
- * e_book_commit_vcard:
- */
+
+
gboolean
-e_book_commit_vcard (EBook *book,
- const char *vcard,
- EBookCallback cb,
- gpointer closure)
+e_book_remove (EBook *book,
+ GError **error)
{
CORBA_Environment ev;
+ EBookOp *our_op;
+ EBookStatus status;
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (vcard != NULL, FALSE);
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_commit_vcard: No URI loaded!\n");
+ e_mutex_lock (book->priv->mutex);
+
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED,
+ _("e_book_remove on book before e_book_load_uri"));
return FALSE;
}
- CORBA_exception_init (&ev);
+ if (book->priv->current_op != NULL) {
+ e_mutex_unlock (book->priv->mutex);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY,
+ _("book busy"));
+ return FALSE;
+ }
- e_book_queue_op (book, cb, closure, NULL);
+ our_op = e_book_new_op (book);
- GNOME_Evolution_Addressbook_Book_modifyCard (
- book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev);
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (book->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ /* will eventually end up calling e_book_response_remove */
+ GNOME_Evolution_Addressbook_Book_remove (book->priv->corba_book, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_commit_vcard: Exception "
- "modifying card in PAS!\n");
+
+ e_book_clear_op (book, our_op);
+
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
+
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
+ _("Corba exception making Book::remove call"));
return FALSE;
}
CORBA_exception_free (&ev);
- return TRUE;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_book_clear_op (book, our_op);
+
+ E_BOOK_CHECK_STATUS (status, error);
}
-/**
- * e_book_check_connection:
- */
-gboolean
-e_book_check_connection (EBook *book)
+static void
+e_book_response_remove (EBook *book,
+ EBookStatus status)
{
- CORBA_Environment ev;
+ EBookOp *op;
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
+ printf ("e_book_response_remove\n");
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_check_connection: No URI loaded!\n");
- return FALSE;
+ op = e_book_get_op (book);
+
+ if (op == NULL) {
+ g_warning ("e_book_response_remove: Cannot find operation ");
+ return;
}
- CORBA_exception_init (&ev);
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
- GNOME_Evolution_Addressbook_Book_checkConnection (book->priv->corba_book, &ev);
+
+static void
+e_book_handle_response (EBookListener *listener, EBookListenerResponse *resp, EBook *book)
+{
+ switch (resp->op) {
+ case CreateContactResponse:
+ e_book_response_add_contact (book, resp->status, resp->id);
+ break;
+ case RemoveContactResponse:
+ case ModifyContactResponse:
+ case AuthenticationResponse:
+ e_book_response_generic (book, resp->status);
+ break;
+ case GetContactResponse: {
+ EContact *contact = e_contact_new_from_vcard (resp->vcard);
+ e_book_response_get_contact (book, resp->status, contact);
+ break;
+ }
+ case GetContactListResponse:
+ e_book_response_get_contacts (book, resp->status, resp->list);
+ break;
+ case GetBookViewResponse:
+ e_book_response_get_book_view(book, resp->status, resp->book_view);
+ break;
+ case GetChangesResponse:
+ e_book_response_get_changes(book, resp->status, resp->list);
+ break;
+ case OpenBookResponse:
+ e_book_response_open (book, resp->status);
+ break;
+ case RemoveBookResponse:
+ e_book_response_remove (book, resp->status);
+ break;
+ case GetSupportedFieldsResponse:
+ e_book_response_get_supported_fields (book, resp->status, resp->list);
+ break;
+ case GetSupportedAuthMethodsResponse:
+ e_book_response_get_supported_auth_methods (book, resp->status, resp->list);
+ break;
+ case WritableStatusEvent:
+ book->priv->writable = resp->writable;
+ g_signal_emit (book, e_book_signals [WRITABLE_STATUS], 0, resp->writable);
+ break;
+ default:
+ g_error ("EBook: Unknown response code %d!\n",
+ resp->op);
+ }
+}
+
+
+
+gboolean
+e_book_unload_uri (EBook *book,
+ GError **error)
+{
+ CORBA_Environment ev;
+
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (book->priv->load_state != E_BOOK_URI_NOT_LOADED, E_BOOK_ERROR_URI_NOT_LOADED);
+
+ /* Release the remote GNOME_Evolution_Addressbook_Book in the PAS. */
+ CORBA_exception_init (&ev);
+
+ bonobo_object_release_unref (book->priv->corba_book, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_check_connection: Exception "
- "querying the PAS!\n");
- CORBA_exception_free (&ev);
- return FALSE;
+ g_warning ("e_book_unload_uri: Exception releasing "
+ "remote book interface!\n");
}
-
+
CORBA_exception_free (&ev);
+ e_book_listener_stop (book->priv->listener);
+ bonobo_object_unref (BONOBO_OBJECT (book->priv->listener));
+
+ book->priv->listener = NULL;
+ book->priv->load_state = E_BOOK_URI_NOT_LOADED;
+ g_free (book->priv->cap);
+ book->priv->cap = NULL;
+ book->priv->writable = FALSE;
+
return TRUE;
}
-guint
-e_book_get_cursor (EBook *book,
- gchar *query,
- EBookCursorCallback cb,
- gpointer closure)
+
+
+/**
+ * e_book_load_uri:
+ */
+
+static void
+backend_died_cb (EComponentListener *cl, gpointer user_data)
+{
+ EBook *book = user_data;
+
+ book->priv->load_state = E_BOOK_URI_NOT_LOADED;
+ g_signal_emit (book, e_book_signals [BACKEND_DIED], 0);
+}
+
+static GList *
+activate_factories_for_uri (EBook *book, const char *uri)
{
CORBA_Environment ev;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
+ Bonobo_ServerInfoList *info_list = NULL;
+ int i;
+ char *protocol, *query, *colon;
+ GList *factories = NULL;
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_check_connection: No URI loaded!\n");
- return 0;
+ colon = strchr (uri, ':');
+ if (!colon) {
+ g_warning ("e_book_load_uri: Unable to determine protocol in the URI\n");
+ return FALSE;
}
-
- CORBA_exception_init (&ev);
- tag = e_book_queue_op (book, cb, closure, NULL);
+ protocol = g_strndup (uri, colon-uri);
+ query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/BookFactory:1.0')"
+ " AND addressbook:supported_protocols.has ('%s')", protocol
+ );
+
+ CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_Book_getCursor (book->priv->corba_book, query, &ev);
+ info_list = bonobo_activation_query (query, NULL, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_all_cards: Exception "
- "querying list of cards!\n");
+ g_warning ("Eeek! Cannot perform bonobo-activation query for book factories.");
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
+ goto done;
+ return NULL;
}
-
+
+ if (info_list->_length == 0) {
+ g_warning ("Can't find installed BookFactory that handles protocol '%s'.", protocol);
+ CORBA_exception_free (&ev);
+ goto done;
+ }
+
CORBA_exception_free (&ev);
- return tag;
+ for (i = 0; i < info_list->_length; i ++) {
+ const Bonobo_ServerInfo *info;
+ GNOME_Evolution_Addressbook_BookFactory factory;
+
+ info = info_list->_buffer + i;
+
+ factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
+
+ if (factory == CORBA_OBJECT_NIL)
+ g_warning ("e_book_construct: Could not obtain a handle "
+ "to the Personal Addressbook Server with IID `%s'\n", info->iid);
+ else
+ factories = g_list_append (factories, factory);
+ }
+
+ done:
+ if (info_list)
+ CORBA_free (info_list);
+ g_free (query);
+ g_free (protocol);
+
+ return factories;
}
-guint
-e_book_get_book_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure)
+gboolean
+e_book_load_uri (EBook *book,
+ const char *uri,
+ gboolean only_if_exists,
+ GError **error)
{
- CORBA_Environment ev;
- EBookViewListener *listener;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
+ GList *factories;
+ GList *l;
+ gboolean rv = FALSE;
+ GNOME_Evolution_Addressbook_Book corba_book = CORBA_OBJECT_NIL;
+
+ e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG);
+ e_return_error_if_fail (uri, E_BOOK_ERROR_INVALID_ARG);
+
+ /* XXX this needs to happen while holding the book's lock i would think... */
+ e_return_error_if_fail (book->priv->load_state == E_BOOK_URI_NOT_LOADED, E_BOOK_ERROR_URI_ALREADY_LOADED);
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_book_view: No URI loaded!\n");
- return 0;
+ /* try to find a list of factories that can handle the protocol */
+ if (! (factories = activate_factories_for_uri (book, uri))) {
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED,
+ _("e_book_load_uri: no factories available for uri `%s'"), uri);
+ return FALSE;
}
- listener = e_book_view_listener_new();
-
- CORBA_exception_init (&ev);
- tag = e_book_queue_op (book, cb, closure, listener);
-
- GNOME_Evolution_Addressbook_Book_getBookView (book->priv->corba_book, bonobo_object_corba_objref(BONOBO_OBJECT(listener)), query, &ev);
+ book->priv->load_state = E_BOOK_URI_LOADING;
+
+ /*
+ * Create our local BookListener interface.
+ */
+ book->priv->listener = e_book_listener_new ();
+ if (book->priv->listener == NULL) {
+ g_warning ("e_book_load_uri: Could not create EBookListener!\n");
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR,
+ _("e_book_load_uri: Could not create EBookListener"));
+ return FALSE;
+ }
+ book->priv->listener_signal = g_signal_connect (book->priv->listener, "response",
+ G_CALLBACK (e_book_handle_response), book);
+
+ g_free (book->priv->uri);
+ book->priv->uri = g_strdup (uri);
+
+ for (l = factories; l; l = l->next) {
+ GNOME_Evolution_Addressbook_BookFactory factory = l->data;
+ EBookOp *our_op;
+ CORBA_Environment ev;
+ EBookStatus status;
+
+ our_op = e_book_new_op (book);
+
+ e_mutex_lock (our_op->mutex);
+
+ CORBA_exception_init (&ev);
+
+ corba_book = GNOME_Evolution_Addressbook_BookFactory_getBook (factory, book->priv->uri,
+ bonobo_object_corba_objref (BONOBO_OBJECT (book->priv->listener)),
+ &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+
+ e_book_clear_op (book, our_op);
+
+ CORBA_exception_free (&ev);
+ continue;
+ }
+
+ GNOME_Evolution_Addressbook_Book_open (corba_book,
+ only_if_exists,
+ &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ /* kill the listener so the book will die */
+ g_signal_handler_disconnect (book->priv->listener, book->priv->listener_signal);
+ bonobo_object_unref (book->priv->listener);
+ book->priv->listener = NULL;
+
+ e_book_clear_op (book, our_op);
+
+ CORBA_exception_free (&ev);
+ continue;
+ }
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_book_view: Exception "
- "getting book_view!\n");
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ /* remove the op from the book's hash of operations */
+ e_book_clear_op (book, our_op);
+
+ if (status == E_BOOK_ERROR_CANCELLED
+ || status == E_BOOK_ERROR_OK) {
+ rv = TRUE;
+ break;
+ }
}
-
- CORBA_exception_free (&ev);
- return tag;
+ /* free up the factories */
+ for (l = factories; l; l = l->next)
+ CORBA_Object_release ((CORBA_Object)l->data, NULL);
+
+ if (rv == TRUE) {
+ book->priv->corba_book = corba_book;
+ book->priv->load_state = E_BOOK_URI_LOADED;
+ book->priv->comp_listener = e_component_listener_new (book->priv->corba_book);
+ book->priv->died_signal = g_signal_connect (book->priv->comp_listener, "component_died",
+ G_CALLBACK (backend_died_cb), book);
+ return TRUE;
+ }
+ else {
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED,
+ _("e_book_load_uri: no factories available for uri `%s'"), uri);
+ return FALSE;
+ }
+
+ return rv;
}
-guint
-e_book_get_completion_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure)
+gboolean
+e_book_load_local_addressbook (EBook *book,
+ GError **error)
{
- CORBA_Environment ev;
- EBookViewListener *listener;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
+ char *filename;
+ char *uri;
+ gboolean rv;
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_completion_view: No URI loaded!\n");
- return 0;
- }
+ filename = g_build_filename (g_get_home_dir(),
+ "evolution/local/Contacts",
+ NULL);
+ uri = g_strdup_printf ("file://%s", filename);
- listener = e_book_view_listener_new();
+ g_free (filename);
- CORBA_exception_init (&ev);
-
- tag = e_book_queue_op (book, cb, closure, listener);
+ rv = e_book_load_uri (book, uri, TRUE, error);
- GNOME_Evolution_Addressbook_Book_getCompletionView (book->priv->corba_book,
- bonobo_object_corba_objref(BONOBO_OBJECT(listener)),
- query, &ev);
+ g_free (uri);
+
+ return rv;
+}
+
+const char *
+e_book_get_uri (EBook *book)
+{
+ return book->priv->uri;
+}
+
+const char *
+e_book_get_static_capabilities (EBook *book,
+ GError **error)
+{
+ if (!book->priv->cap_queried) {
+ CORBA_Environment ev;
+ char *temp;
+
+ CORBA_exception_init (&ev);
+
+ if (book->priv->load_state != E_BOOK_URI_LOADED) {
+ g_warning ("e_book_unload_uri: No URI is loaded!\n");
+ return g_strdup("");
+ }
+
+ temp = GNOME_Evolution_Addressbook_Book_getStaticCapabilities(book->priv->corba_book, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("e_book_get_static_capabilities: Exception "
+ "during get_static_capabilities!\n");
+ CORBA_exception_free (&ev);
+ return g_strdup("");
+ }
+
+ book->priv->cap = g_strdup(temp);
+ book->priv->cap_queried = TRUE;
+
+ CORBA_free(temp);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_completion_view: Exception "
- "getting completion_view!\n");
CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
}
-
- CORBA_exception_free (&ev);
- return tag;
+ return book->priv->cap;
}
-guint
-e_book_get_changes (EBook *book,
- gchar *changeid,
- EBookBookViewCallback cb,
- gpointer closure)
+gboolean
+e_book_check_static_capability (EBook *book,
+ const char *cap)
{
- CORBA_Environment ev;
- EBookViewListener *listener;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
+ const char *caps = e_book_get_static_capabilities (book, NULL);
+
+ /* XXX this is an inexact test but it works for our use */
+ if (caps && strstr (caps, cap))
+ return TRUE;
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_changes: No URI loaded!\n");
+ return FALSE;
+}
+
+gboolean
+e_book_is_writable (EBook *book)
+{
+ return book->priv->writable;
+}
+
+
+
+
+gboolean
+e_book_get_self (EContact **contact, EBook **book, GError **error)
+{
+ GError *e = NULL;
+
+ if (!e_book_get_default_addressbook (book, &e)) {
+ g_propagate_error (error, e);
return FALSE;
}
- listener = e_book_view_listener_new();
-
- CORBA_exception_init (&ev);
+#if notyet
+ EBook *b;
+ char *self_uri, *self_uid;
- tag = e_book_queue_op (book, cb, closure, listener);
-
- GNOME_Evolution_Addressbook_Book_getChanges (book->priv->corba_book, bonobo_object_corba_objref(BONOBO_OBJECT(listener)), changeid, &ev);
+ /* XXX get the setting for the self book and self uid from gconf */
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_changes: Exception "
- "getting changes!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
+ b = e_book_new();
+ if (! e_book_load_uri (b, self_uri, TRUE, error)) {
+ g_object_unref (b);
+ return FALSE;
}
-
- CORBA_exception_free (&ev);
- return tag;
-}
+ if (! e_book_get_contact (b, self_uid,
+ contact, error)) {
+ g_object_unref (b);
+ return FALSE;
+ }
-/**
- * e_book_cancel
- */
+ if (book)
+ *book = b;
+ else
+ g_object_unref (b);
+ return TRUE;
+#endif
+}
-void
-e_book_cancel (EBook *book, guint tag)
+gboolean
+e_book_set_self (EBook *book, const char *id, GError **error)
{
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
- g_return_if_fail (tag != 0);
-
- /* In an attempt to be useful, we take a bit of extra care in reporting
- errors. This might come in handy someday. */
- if (tag >= book->priv->op_tag)
- g_warning ("Attempt to cancel unassigned operation (%u)", tag);
- else if (! e_book_cancel_op (book, tag))
- g_warning ("Attempt to cancel unknown operation (%u)", tag);
}
-/**
- * e_book_get_name:
- */
-char *
-e_book_get_name (EBook *book)
+
+
+gboolean
+e_book_get_default_addressbook (EBook **book, GError **error)
{
- CORBA_Environment ev;
- char *retval;
- char *name;
+ /* XXX for now just load the local ~/evolution/local/Contacts */
+ char *path, *uri;
+ gboolean rv;
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (E_IS_BOOK (book), NULL);
+ *book = e_book_new ();
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_name: No URI loaded!\n");
- return NULL;
- }
+ path = g_build_filename (g_get_home_dir (),
+ "evolution/local/Contacts",
+ NULL);
+ uri = g_strdup_printf ("file://%s", path);
+ g_free (path);
- CORBA_exception_init (&ev);
+ rv = e_book_load_uri (*book, uri, FALSE, error);
- name = GNOME_Evolution_Addressbook_Book_getName (book->priv->corba_book, &ev);
+ g_free (uri);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_name: Exception getting name from PAS!\n");
- CORBA_exception_free (&ev);
- return NULL;
+ if (!rv) {
+ g_object_unref (*book);
+ *book = NULL;
}
- CORBA_exception_free (&ev);
+ return rv;
+#if notyet
+ EConfigListener *listener = e_config_listener_new ();
+ ESourceList *sources = ...;
+ ESource *default_source;
+
+ default_source = e_source_list_peek_source_by_uid (sources,
+ "default_");
+#endif
+}
- if (name == NULL) {
- g_warning ("e_book_get_name: Got NULL name from PAS!\n");
- return NULL;
+#if notyet
+ESourceList*
+e_book_get_addressbooks (GError **error)
+{
+}
+#endif
+
+
+static void*
+startup_mainloop (void *arg)
+{
+ bonobo_main();
+ return NULL;
+}
+
+/* one-time start up for libebook */
+static void
+e_book_activate()
+{
+ static GStaticMutex e_book_lock = G_STATIC_MUTEX_INIT;
+ static gboolean activated = FALSE;
+
+ g_static_mutex_lock (&e_book_lock);
+ if (!activated) {
+ pthread_t ebook_mainloop_thread;
+ activated = TRUE;
+ pthread_create(&ebook_mainloop_thread, NULL, startup_mainloop, NULL);
}
+ g_static_mutex_unlock (&e_book_lock);
+}
- retval = g_strdup (name);
- CORBA_free (name);
+
- return retval;
+EBook*
+e_book_new (void)
+{
+ e_book_activate ();
+ return g_object_new (E_TYPE_BOOK, NULL);
}
+
static void
e_book_init (EBook *book)
{
book->priv = g_new0 (EBookPrivate, 1);
- book->priv->load_state = URINotLoaded;
- book->priv->op_tag = 1;
+ book->priv->load_state = E_BOOK_URI_NOT_LOADED;
book->priv->uri = NULL;
+ book->priv->mutex = e_mutex_new (E_MUTEX_REC);
}
static void
@@ -1598,8 +1967,8 @@ e_book_dispose (GObject *object)
book->priv->comp_listener = NULL;
}
- if (book->priv->load_state == URILoaded)
- e_book_unload_uri (book);
+ if (book->priv->load_state == E_BOOK_URI_LOADED)
+ e_book_unload_uri (book, NULL);
CORBA_exception_init (&ev);
@@ -1640,16 +2009,6 @@ e_book_class_init (EBookClass *klass)
parent_class = g_type_class_ref (G_TYPE_OBJECT);
- e_book_signals [LINK_STATUS] =
- g_signal_new ("link_status",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EBookClass, link_status),
- NULL, NULL,
- e_book_marshal_NONE__BOOL,
- G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
-
e_book_signals [WRITABLE_STATUS] =
g_signal_new ("writable_status",
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/addressbook/backend/ebook/e-book.h b/addressbook/backend/ebook/e-book.h
index d2c5a7bce4..1d2a4dc2d4 100644
--- a/addressbook/backend/ebook/e-book.h
+++ b/addressbook/backend/ebook/e-book.h
@@ -3,9 +3,9 @@
* The Evolution addressbook client object.
*
* Author:
- * Nat Friedman (nat@ximian.com)
+ * Chris Toshok (toshok@ximian.com)
*
- * Copyright 1999, 2000, Ximian, Inc.
+ * Copyright (C) 1999-2003, Ximian, Inc.
*/
#ifndef __E_BOOK_H__
@@ -14,10 +14,13 @@
#include <glib.h>
#include <glib-object.h>
-#include <ebook/e-card.h>
-#include <ebook/e-card-cursor.h>
+#include <ebook/e-contact.h>
+#include <ebook/e-book-query.h>
#include <ebook/e-book-view.h>
#include <ebook/e-book-types.h>
+#if notyet
+#include <e-util/e-source-list.h>
+#endif
#define E_TYPE_BOOK (e_book_get_type ())
#define E_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK, EBook))
@@ -43,127 +46,120 @@ struct _EBookClass {
/*
* Signals.
*/
- void (* open_progress) (EBook *book, const char *msg, short percent);
- void (* link_status) (EBook *book, gboolean connected);
void (* writable_status) (EBook *book, gboolean writable);
void (* backend_died) (EBook *book);
-};
-/* Callbacks for asynchronous functions. */
-typedef void (*EBookCallback) (EBook *book, EBookStatus status, gpointer closure);
-typedef void (*EBookOpenProgressCallback) (EBook *book,
- const char *status_message,
- short percent,
- gpointer closure);
-typedef void (*EBookIdCallback) (EBook *book, EBookStatus status, const char *id, gpointer closure);
-typedef void (*EBookCardCallback) (EBook *book, EBookStatus status, ECard *card, gpointer closure);
-typedef void (*EBookCursorCallback) (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure);
-typedef void (*EBookBookViewCallback) (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure);
-typedef void (*EBookFieldsCallback) (EBook *book, EBookStatus status, EList *fields, gpointer closure);
-typedef void (*EBookAuthMethodsCallback) (EBook *book, EBookStatus status, EList *auth_methods, gpointer closure);
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
+};
/* Creating a new addressbook. */
-EBook *e_book_new (void);
+EBook *e_book_new (void);
+
+/* loading arbitrary addressbooks */
+gboolean e_book_load_uri (EBook *book,
+ const char *uri,
+ gboolean only_if_exists,
+ GError **error);
-void e_book_load_uri (EBook *book,
- const char *uri,
- EBookCallback open_response,
- gpointer closure);
-void e_book_unload_uri (EBook *book);
+gboolean e_book_unload_uri (EBook *book,
+ GError **error);
-const char *e_book_get_uri (EBook *book);
+gboolean e_book_remove (EBook *book,
+ GError **error);
-char *e_book_get_static_capabilities (EBook *book);
-gboolean e_book_check_static_capability (EBook *book, const char *cap);
+/* convenience function for loading the "local" contact folder */
+gboolean e_book_load_local_addressbook (EBook *book,
+ GError **error);
-guint e_book_get_supported_fields (EBook *book,
- EBookFieldsCallback cb,
- gpointer closure);
+gboolean e_book_get_supported_fields (EBook *book,
+ GList **fields,
+ GError **error);
-guint e_book_get_supported_auth_methods (EBook *book,
- EBookAuthMethodsCallback cb,
- gpointer closure);
+gboolean e_book_get_supported_auth_methods (EBook *book,
+ GList **auth_methods,
+ GError **error);
/* User authentication. */
-void e_book_authenticate_user (EBook *book,
- const char *user,
- const char *passwd,
- const char *auth_method,
- EBookCallback cb,
- gpointer closure);
-
-/* Fetching cards. */
-guint e_book_get_card (EBook *book,
- const char *id,
- EBookCardCallback cb,
- gpointer closure);
-
-/* Deleting cards. */
-gboolean e_book_remove_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure);
-gboolean e_book_remove_card_by_id (EBook *book,
- const char *id,
- EBookCallback cb,
- gpointer closure);
-
-gboolean e_book_remove_cards (EBook *book,
- GList *id_list,
- EBookCallback cb,
- gpointer closure);
-
-/* Adding cards. */
-gboolean e_book_add_card (EBook *book,
- ECard *card,
- EBookIdCallback cb,
- gpointer closure);
-gboolean e_book_add_vcard (EBook *book,
- const char *vcard,
- EBookIdCallback cb,
- gpointer closure);
-
-/* Modifying cards. */
-gboolean e_book_commit_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure);
-gboolean e_book_commit_vcard (EBook *book,
- const char *vcard,
- EBookCallback cb,
- gpointer closure);
-
-/* Checking to see if we're connected to the card repository. */
-gboolean e_book_check_connection (EBook *book);
-guint e_book_get_cursor (EBook *book,
- char *query,
- EBookCursorCallback cb,
- gpointer closure);
-
-guint e_book_get_book_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure);
-
-guint e_book_get_completion_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure);
-
-guint e_book_get_changes (EBook *book,
- char *changeid,
- EBookBookViewCallback cb,
- gpointer closure);
+gboolean e_book_authenticate_user (EBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method,
+ GError **error);
+
+/* Fetching contacts. */
+gboolean e_book_get_contact (EBook *book,
+ const char *id,
+ EContact **contact,
+ GError **error);
+
+/* Deleting contacts. */
+gboolean e_book_remove_contact (EBook *book,
+ const char *id,
+ GError **error);
+
+gboolean e_book_remove_contacts (EBook *book,
+ GList *id_list,
+ GError **error);
+
+/* Adding contacts. */
+gboolean e_book_add_contact (EBook *book,
+ EContact *contact,
+ GError **error);
+
+/* Modifying contacts. */
+gboolean e_book_commit_contact (EBook *book,
+ EContact *contact,
+ GError **error);
+
+/* Returns a live view of a query. */
+gboolean e_book_get_book_view (EBook *book,
+ EBookQuery *query,
+ GList *requested_fields,
+ int max_results,
+ EBookView **book_view,
+ GError **error);
+
+/* Returns a static snapshot of a query. */
+gboolean e_book_get_contacts (EBook *book,
+ EBookQuery *query,
+ GList **contacts,
+ GError **error);
+
+gboolean e_book_get_changes (EBook *book,
+ char *changeid,
+ GList **changes,
+ GError **error);
+
+void e_book_free_change_list (GList *change_list);
+
+const char *e_book_get_uri (EBook *book);
+
+const char *e_book_get_static_capabilities (EBook *book,
+ GError **error);
+gboolean e_book_check_static_capability (EBook *book,
+ const char *cap);
+gboolean e_book_is_writable (EBook *book);
/* Cancel a pending operation. */
-void e_book_cancel (EBook *book,
- guint tag);
+gboolean e_book_cancel (EBook *book,
+ GError **error);
+/* Identity */
+gboolean e_book_get_self (EContact **contact, EBook **book, GError **error);
+gboolean e_book_set_self (EBook *book, const char *id, GError **error);
-/* Getting the name of the repository. */
-char *e_book_get_name (EBook *book);
+/* Addressbook Discovery */
+gboolean e_book_get_default_addressbook (EBook **book, GError **error);
+#if notyet
+gboolean e_book_get_addressbooks (ESourceList** addressbook_sources, GError **error);
+#endif
-GType e_book_get_type (void);
+GType e_book_get_type (void);
G_END_DECLS
diff --git a/addressbook/backend/ebook/e-card-compare.h b/addressbook/backend/ebook/e-card-compare.h
deleted file mode 100644
index 07ccb54e89..0000000000
--- a/addressbook/backend/ebook/e-card-compare.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-card-compare.h
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#ifndef __E_CARD_COMPARE_H__
-#define __E_CARD_COMPARE_H__
-
-#include "e-book.h"
-#include "e-card.h"
-
-typedef enum {
- E_CARD_MATCH_NOT_APPLICABLE = 0,
- E_CARD_MATCH_NONE = 1,
- E_CARD_MATCH_VAGUE = 2,
- E_CARD_MATCH_PARTIAL = 3,
- E_CARD_MATCH_EXACT = 4
-} ECardMatchType;
-
-typedef enum {
- E_CARD_MATCH_PART_NOT_APPLICABLE = -1,
- E_CARD_MATCH_PART_NONE = 0,
- E_CARD_MATCH_PART_GIVEN_NAME = 1<<0,
- E_CARD_MATCH_PART_ADDITIONAL_NAME = 1<<2,
- E_CARD_MATCH_PART_FAMILY_NAME = 1<<3
-} ECardMatchPart;
-
-typedef void (*ECardMatchQueryCallback) (ECard *card, ECard *match, ECardMatchType type, gpointer closure);
-
-ECardMatchType e_card_compare_name_to_string (ECard *card, const gchar *str);
-
-ECardMatchType e_card_compare_name_to_string_full (ECard *card, const gchar *str,
- gboolean allow_partial_matches,
- gint *matched_parts, ECardMatchPart *first_matched_part,
- gint *matched_character_count);
-
-ECardMatchType e_card_compare_name (ECard *card1, ECard *card2);
-ECardMatchType e_card_compare_nickname (ECard *card1, ECard *card2);
-ECardMatchType e_card_compare_email (ECard *card1, ECard *card2);
-ECardMatchType e_card_compare_address (ECard *card1, ECard *card2);
-ECardMatchType e_card_compare_telephone (ECard *card1, ECard *card2);
-
-ECardMatchType e_card_compare (ECard *card1, ECard *card2);
-
-void e_card_locate_match (ECard *card, ECardMatchQueryCallback cb, gpointer closure);
-void e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQueryCallback cb, gpointer closure);
-
-
-
-#endif /* __E_CARD_COMPARE_H__ */
-
diff --git a/addressbook/backend/ebook/e-card-cursor.c b/addressbook/backend/ebook/e-card-cursor.c
deleted file mode 100644
index 0aa9c8c1e0..0000000000
--- a/addressbook/backend/ebook/e-card-cursor.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-card-cursor.c: Implements card cursors.
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com.
- */
-
-#include <config.h>
-#include "addressbook.h"
-#include "e-card-cursor.h"
-
-struct _ECardCursorPrivate {
- GNOME_Evolution_Addressbook_CardCursor corba_cursor;
-};
-
-/*
- * A pointer to our parent object class
- */
-static GObjectClass *parent_class;
-
-/*
- * Implemented GObject::dispose
- */
-static void
-e_card_cursor_dispose (GObject *object)
-{
- ECardCursor *cursor = E_CARD_CURSOR (object);
-
- if (cursor->priv) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_CardCursor_unref( cursor->priv->corba_cursor, &ev );
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_destroy: Exception unreffing "
- "corba cursor.\n");
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
- }
-
- CORBA_Object_release (cursor->priv->corba_cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_destroy: Exception releasing "
- "corba cursor.\n");
- }
-
- CORBA_exception_free (&ev);
-
- g_free ( cursor->priv );
- cursor->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/**
- * e_card_cursor_get_length:
- * @cursor: the #ECardCursor whose length is being queried
- *
- * Returns: the number of items the cursor references, or -1 there's
- * an error.
- */
-long
-e_card_cursor_get_length (ECardCursor *cursor)
-{
- if ( cursor->priv->corba_cursor != CORBA_OBJECT_NIL ) {
- CORBA_Environment ev;
- long ret_val;
-
- CORBA_exception_init (&ev);
-
- ret_val = GNOME_Evolution_Addressbook_CardCursor_count (cursor->priv->corba_cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_get_length: Exception during "
- "get_length corba call.\n");
- ret_val = -1;
- }
-
- CORBA_exception_free (&ev);
-
- return ret_val;
- }
- else
- return -1;
-}
-
-/**
- * e_card_cursor_get_nth:
- * @cursor: an #ECardCursor object
- * @n: the index of the item requested
- *
- * Gets an #ECard based on an index.
- *
- * Returns: a new #ECard on success, or %NULL on failure.
- */
-ECard *
-e_card_cursor_get_nth (ECardCursor *cursor,
- const long n)
-{
- if ( cursor->priv->corba_cursor != CORBA_OBJECT_NIL ) {
- CORBA_Environment en;
- CORBA_char *vcard;
- ECard *card;
-
- CORBA_exception_init (&en);
-
- vcard = GNOME_Evolution_Addressbook_CardCursor_getNth(cursor->priv->corba_cursor, n, &en);
-
- if (en._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_get_nth: Exception during "
- "get_nth corba call.\n");
- }
-
- CORBA_exception_free (&en);
-
- card = e_card_new (vcard);
-
- CORBA_free(vcard);
-
- return card;
- }
- else
- return e_card_new("");
-}
-
-static void
-e_card_cursor_class_init (ECardCursorClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- object_class->dispose = e_card_cursor_dispose;
-}
-
-static void
-e_card_cursor_init (ECardCursor *cursor)
-{
- cursor->priv = g_new(ECardCursorPrivate, 1);
- cursor->priv->corba_cursor = CORBA_OBJECT_NIL;
-}
-
-GType
-e_card_cursor_get_type (void)
-{
- static GType type = 0;
-
- if (!type){
- static const GTypeInfo info = {
- sizeof (ECardCursorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_card_cursor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ECardCursor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_card_cursor_init,
- };
-
- type = g_type_register_static (G_TYPE_OBJECT, "ECardCursor", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_card_cursor_construct:
- * @cursor: an #ECardCursor object
- * @corba_cursor: an #GNOME_Evolution_Addressbook_CardCursor
- *
- * Wraps an #GNOME_Evolution_Addressbook_CardCursor object inside the #ECardCursor
- * @cursor object.
- *
- * Returns: a new #ECardCursor on success, or %NULL on failure.
- */
-ECardCursor *
-e_card_cursor_construct (ECardCursor *cursor,
- GNOME_Evolution_Addressbook_CardCursor corba_cursor)
-{
- CORBA_Environment ev;
- g_return_val_if_fail (cursor != NULL, NULL);
- g_return_val_if_fail (E_IS_CARD_CURSOR (cursor), NULL);
- g_return_val_if_fail (corba_cursor != CORBA_OBJECT_NIL, NULL);
-
- CORBA_exception_init (&ev);
-
- /*
- * Initialize cursor
- */
- cursor->priv->corba_cursor = CORBA_Object_duplicate(corba_cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_construct: Exception duplicating "
- "corba cursor.\n");
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
- }
-
- GNOME_Evolution_Addressbook_CardCursor_ref(cursor->priv->corba_cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("e_card_cursor_construct: Exception reffing "
- "corba cursor.\n");
- }
-
- CORBA_exception_free (&ev);
-
- /*
- * Success: return the GType we were given
- */
- return cursor;
-}
-
-/**
- * e_card_cursor_new:
- * @cursor: the #GNOME_Evolution_Addressbook_CardCursor to be wrapped
- *
- * Creates a new #ECardCursor, which wraps an #GNOME_Evolution_Addressbook_CardCursor
- * object.
- *
- * Returns: a new #ECardCursor on success, or %NULL on failure.
- */
-ECardCursor *
-e_card_cursor_new (GNOME_Evolution_Addressbook_CardCursor corba_cursor)
-{
- ECardCursor *cursor;
-
- cursor = g_object_new (E_TYPE_CARD_CURSOR, NULL);
-
- return e_card_cursor_construct (cursor,
- corba_cursor);
-}
diff --git a/addressbook/backend/ebook/e-card-cursor.h b/addressbook/backend/ebook/e-card-cursor.h
deleted file mode 100644
index b8da39f023..0000000000
--- a/addressbook/backend/ebook/e-card-cursor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __E_CARD_CURSOR_H__
-#define __E_CARD_CURSOR_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <ebook/addressbook.h>
-#include <ebook/e-card.h>
-
-#define E_TYPE_CARD_CURSOR (e_card_cursor_get_type ())
-#define E_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_CARD_CURSOR, ECardCursor))
-#define E_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_CARD_CURSOR, ECardCursorClass))
-#define E_IS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_CARD_CURSOR))
-#define E_IS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_CARD_CURSOR))
-#define E_CARD_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD_CURSOR, ECardCursorClass))
-
-G_BEGIN_DECLS
-
-typedef struct _ECardCursor ECardCursor;
-typedef struct _ECardCursorPrivate ECardCursorPrivate;
-typedef struct _ECardCursorClass ECardCursorClass;
-
-struct _ECardCursor {
- GObject parent;
- ECardCursorPrivate *priv;
-};
-
-struct _ECardCursorClass {
- GObjectClass parent;
-};
-
-/* Creating a new addressbook. */
-ECardCursor *e_card_cursor_new (GNOME_Evolution_Addressbook_CardCursor corba_cursor);
-ECardCursor *e_card_cursor_construct (ECardCursor *cursor,
- GNOME_Evolution_Addressbook_CardCursor corba_cursor);
-
-GType e_card_cursor_get_type (void);
-
-/* Fetching cards. */
-long e_card_cursor_get_length (ECardCursor *cursor);
-ECard *e_card_cursor_get_nth (ECardCursor *cursor,
- const long nth);
-G_END_DECLS
-
-#endif /* ! __E_CARD_CURSOR_H__ */
diff --git a/addressbook/backend/ebook/e-card-pairs.h b/addressbook/backend/ebook/e-card-pairs.h
deleted file mode 100644
index f82f948ebb..0000000000
--- a/addressbook/backend/ebook/e-card-pairs.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* GnomeCard - a graphical contact manager.
- *
- * pairs.h: This file is part of GnomeCard.
- *
- * Copyright (C) 1999 The Free Software Foundation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __E_CARD_PAIRS_H__
-#define __E_CARD_PAIRS_H__
-
-#include <libversit/vcc.h>
-#include <ebook/e-card.h>
-
-
-#if 0
-struct pair
-{
- char *str;
- ECardPropertyType i ;
-};
-
-struct pair prop_lookup[] = {
- { VCFullNameProp, PROP_FNAME },
- { VCNameProp, PROP_NAME },
- { VCPhotoProp, PROP_PHOTO },
- { VCBirthDateProp, PROP_BDAY },
- { VCAdrProp, PROP_DELADDR },
- { VCDeliveryLabelProp, PROP_DELLABEL },
- { VCTelephoneProp, PROP_PHONE },
- { VCEmailAddressProp, PROP_EMAIL },
- { VCMailerProp, PROP_MAILER },
- { VCTimeZoneProp, PROP_TIMEZN },
- { VCGeoProp, PROP_GEOPOS },
- { VCTitleProp, PROP_TITLE },
- { VCBusinessRoleProp, PROP_ROLE },
- { VCLogoProp, PROP_LOGO },
- { VCAgentProp, PROP_AGENT },
- { VCOrgProp, PROP_ORG },
- { VCCategoriesProp, PROP_CATEGORIES },
- { VCCommentProp, PROP_COMMENT },
- { VCLastRevisedProp, PROP_REV },
- { VCPronunciationProp, PROP_SOUND },
- { VCURLProp, PROP_URL },
- { VCUniqueStringProp, PROP_UID },
- { VCVersionProp, PROP_VERSION },
- { VCPublicKeyProp, PROP_KEY },
- { VCValueProp, PROP_VALUE },
- { VCEncodingProp, PROP_ENCODING },
- { VCQuotedPrintableProp, PROP_QUOTED_PRINTABLE },
- { VC8bitProp, PROP_8BIT },
- { VCBase64Prop, PROP_BASE64 },
- { VCLanguageProp, PROP_LANG },
- { VCCharSetProp, PROP_CHARSET },
- { NULL, PROP_NONE} };
-
-struct pair photo_pairs[] = {
- { VCGIFProp, PHOTO_GIF },
- { VCCGMProp, PHOTO_CGM },
- { VCWMFProp, PHOTO_WMF },
- { VCBMPProp, PHOTO_BMP },
- { VCMETProp, PHOTO_MET },
- { VCPMBProp, PHOTO_PMB },
- { VCDIBProp, PHOTO_DIB },
- { VCPICTProp, PHOTO_PICT },
- { VCTIFFProp, PHOTO_TIFF },
- { VCPDFProp, PHOTO_PDF },
- { VCPSProp, PHOTO_PS },
- { VCJPEGProp, PHOTO_JPEG },
- { VCMPEGProp, PHOTO_MPEG },
- { VCMPEG2Prop, PHOTO_MPEG2 },
- { VCAVIProp, PHOTO_AVI },
- { VCQuickTimeProp, PHOTO_QTIME },
- { NULL, 0 } };
-
-struct pair email_pairs[] = {
- { VCAOLProp, EMAIL_AOL },
- { VCAppleLinkProp, EMAIL_APPLE_LINK },
- { VCATTMailProp, EMAIL_ATT },
- { VCCISProp, EMAIL_CIS },
- { VCEWorldProp, EMAIL_EWORLD },
- { VCInternetProp, EMAIL_INET },
- { VCIBMMailProp, EMAIL_IBM },
- { VCMCIMailProp, EMAIL_MCI },
- { VCPowerShareProp, EMAIL_POWERSHARE },
- { VCProdigyProp, EMAIL_PRODIGY },
- { VCTLXProp, EMAIL_TLX },
- { VCX400Prop, EMAIL_X400 },
- { NULL, 0 } };
-
-struct pair sound_pairs[] = {
- { VCAIFFProp, SOUND_AIFF },
- { VCPCMProp, SOUND_PCM },
- { VCWAVEProp, SOUND_WAVE },
- { NULL, 0 } };
-
-struct pair key_pairs[] = {
- { VCX509Prop, KEY_X509 },
- { VCPGPProp, KEY_PGP },
- { NULL, 0 } };
-
-
-#endif
-#endif /* ! __E_CARD_PAIRS_H__ */
diff --git a/addressbook/backend/ebook/e-card-simple.c b/addressbook/backend/ebook/e-card-simple.c
deleted file mode 100644
index b9e32762fe..0000000000
--- a/addressbook/backend/ebook/e-card-simple.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Arturo Espinosa (arturo@nuclecu.unam.mx)
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 1999 The Free Software Foundation
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <bonobo/bonobo-i18n.h>
-#include <gal/util/e-util.h>
-
-#include <libversit/vcc.h>
-#include "e-card-simple.h"
-
-/* Object property IDs */
-enum {
- PROP_0,
- PROP_CARD,
-};
-
-static GObjectClass *parent_class;
-
-typedef enum _ECardSimpleInternalType ECardSimpleInternalType;
-typedef struct _ECardSimpleFieldData ECardSimpleFieldData;
-
-enum _ECardSimpleInternalType {
- E_CARD_SIMPLE_INTERNAL_TYPE_STRING,
- E_CARD_SIMPLE_INTERNAL_TYPE_DATE,
- E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS,
- E_CARD_SIMPLE_INTERNAL_TYPE_PHONE,
- E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL,
- E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL,
- E_CARD_SIMPLE_INTERNAL_TYPE_BOOL,
-};
-
-struct _ECardSimpleFieldData {
- ECardSimpleField field;
- char *ecard_field;
- char *name;
- char *short_name;
- int list_type_index;
- ECardSimpleInternalType type;
-};
-
-/* This order must match the order in the .h. */
-
-/* the ecard_field data below should only be used for TYPE_STRING,
- TYPE_DATE, and TYPE_SPECIAL fields. that is, it's only valid for
- e-cards for those types. it is used as a unique name for fields
- for the get_supported functionality. */
-static ECardSimpleFieldData field_data[] =
-{
- { E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", N_("File As"), "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", N_("Name"), N_("Name"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_EMAIL, "email", N_("Email"), N_("Email"), E_CARD_SIMPLE_EMAIL_ID_EMAIL, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL },
- { E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, "primary_phone", N_("Primary"), N_("Prim"), E_CARD_SIMPLE_PHONE_ID_PRIMARY, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, "assistant_phone", N_("Assistant"), N_("Assistant"),E_CARD_SIMPLE_PHONE_ID_ASSISTANT, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, "business_phone", N_("Business"), N_("Bus"), E_CARD_SIMPLE_PHONE_ID_BUSINESS, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, "callback_phone", N_("Callback"), N_("Callback"), E_CARD_SIMPLE_PHONE_ID_CALLBACK, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_COMPANY, "company_phone", N_("Company"), N_("Comp"), E_CARD_SIMPLE_PHONE_ID_COMPANY, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_HOME, "home_phone", N_("Home"), N_("Home"), E_CARD_SIMPLE_PHONE_ID_HOME, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_ORG, "org", N_("Organization"), N_("Org"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, "business_address",N_("Business"), N_("Bus"), E_CARD_SIMPLE_ADDRESS_ID_BUSINESS, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS },
- { E_CARD_SIMPLE_FIELD_ADDRESS_HOME, "home_address", N_("Home"), N_("Home"), E_CARD_SIMPLE_ADDRESS_ID_HOME, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS },
- { E_CARD_SIMPLE_FIELD_PHONE_MOBILE, "mobile_phone", N_("Mobile"), N_("Mobile"), E_CARD_SIMPLE_PHONE_ID_MOBILE, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_CAR, "car_phone", N_("Car"), N_("Car"), E_CARD_SIMPLE_PHONE_ID_CAR, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, "business_fax", N_("Business Fax"), N_("Bus Fax"), E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, "home_fax", N_("Home Fax"), N_("Home Fax"), E_CARD_SIMPLE_PHONE_ID_HOME_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, "business_phone_2",N_("Business 2"), N_("Bus 2"), E_CARD_SIMPLE_PHONE_ID_BUSINESS_2, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_HOME_2, "home_phone_2", N_("Home 2"), N_("Home 2"), E_CARD_SIMPLE_PHONE_ID_HOME_2, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_ISDN, "isdn", N_("ISDN"), N_("ISDN"), E_CARD_SIMPLE_PHONE_ID_ISDN, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_OTHER, "other_phone", N_("Other"), N_("Other"), E_CARD_SIMPLE_PHONE_ID_OTHER, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, "other_fax", N_("Other Fax"), N_("Other Fax"), E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_PAGER, "pager", N_("Pager"), N_("Pager"), E_CARD_SIMPLE_PHONE_ID_PAGER, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_RADIO, "radio", N_("Radio"), N_("Radio"), E_CARD_SIMPLE_PHONE_ID_RADIO, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_TELEX, "telex", N_("Telex"), N_("Telex"), E_CARD_SIMPLE_PHONE_ID_TELEX, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, "tty", N_("TTY"), N_("TTY"), E_CARD_SIMPLE_PHONE_ID_TTYTDD, E_CARD_SIMPLE_INTERNAL_TYPE_PHONE },
- { E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, "other_address", N_("Other"), N_("Other"), E_CARD_SIMPLE_ADDRESS_ID_OTHER, E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS },
- { E_CARD_SIMPLE_FIELD_EMAIL_2, "email_2", N_("Email 2"), N_("Email 2"), E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL },
- { E_CARD_SIMPLE_FIELD_EMAIL_3, "email_3", N_("Email 3"), N_("Email 3"), E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL },
- { E_CARD_SIMPLE_FIELD_URL, "url", N_("Web Site"), N_("Url"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", N_("Department"), N_("Dep"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_OFFICE, "office", N_("Office"), N_("Off"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_TITLE, "title", N_("Title"), N_("Title"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ROLE, "role", N_("Profession"), N_("Prof"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_MANAGER, "manager", N_("Manager"), N_("Man"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", N_("Assistant"), N_("Ass"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", N_("Nickname"), N_("Nick"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", N_("Spouse"), N_("Spouse"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_NOTE, "note", N_("Note"), N_("Note"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_CALURI, "caluri", N_("Calendar URI"), N_("CALUri"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_FBURL, "fburl", N_("Free-busy URL"), N_("FBUrl"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ICSCALENDAR, "icscalendar", N_("Default server calendar"), N_("icsCalendar"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_ANNIVERSARY, "anniversary", N_("Anniversary"), N_("Anniv"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_DATE },
- { E_CARD_SIMPLE_FIELD_BIRTH_DATE, "birth_date", N_("Birth Date"), "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_DATE },
- { E_CARD_SIMPLE_FIELD_MAILER, "mailer", "", "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_NAME_OR_ORG, "nameororg", "", "", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL },
- { E_CARD_SIMPLE_FIELD_CATEGORIES, "categories", N_("Categories"), N_("Categories"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_STRING },
- { E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", N_("Family Name"), N_("Family Name"), 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL },
- { E_CARD_SIMPLE_FIELD_GIVEN_NAME, "given_name", "Given Name", "Given Name", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL },
- { E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME, "additional_name", "Additional Name", "Additional Name", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL },
- { E_CARD_SIMPLE_FIELD_NAME_SUFFIX, "name_suffix", "Name Suffix", "Name Suffix", 0, E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL },
- { E_CARD_SIMPLE_FIELD_WANTS_HTML, "wants_html", "Wants HTML", "Wants HTML", 0, E_CARD_SIMPLE_INTERNAL_TYPE_BOOL },
- { E_CARD_SIMPLE_FIELD_IS_LIST, "list", "Is List", "Is List", 0, E_CARD_SIMPLE_INTERNAL_TYPE_BOOL },
-};
-static int field_data_count = sizeof (field_data) / sizeof (field_data[0]);
-
-static void e_card_simple_init (ECardSimple *simple);
-static void e_card_simple_class_init (ECardSimpleClass *klass);
-
-static void e_card_simple_dispose (GObject *object);
-static void e_card_simple_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_card_simple_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-
-static void fill_in_info(ECardSimple *simple);
-
-ECardPhoneFlags phone_correspondences[] = {
- E_CARD_PHONE_ASSISTANT, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */
- E_CARD_PHONE_WORK | E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS, */
- E_CARD_PHONE_WORK | E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS_2, */
- E_CARD_PHONE_WORK | E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX, */
- E_CARD_PHONE_CALLBACK, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */
- E_CARD_PHONE_CAR, /* E_CARD_SIMPLE_PHONE_ID_CAR, */
- E_CARD_PHONE_WORK, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */
- E_CARD_PHONE_HOME, /* E_CARD_SIMPLE_PHONE_ID_HOME, */
- E_CARD_PHONE_HOME, /* E_CARD_SIMPLE_PHONE_ID_HOME_2, */
- E_CARD_PHONE_HOME | E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_HOME_FAX, */
- E_CARD_PHONE_ISDN, /* E_CARD_SIMPLE_PHONE_ID_ISDN, */
- E_CARD_PHONE_CELL, /* E_CARD_SIMPLE_PHONE_ID_MOBILE, */
- E_CARD_PHONE_VOICE, /* E_CARD_SIMPLE_PHONE_ID_OTHER, */
- E_CARD_PHONE_FAX, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */
- E_CARD_PHONE_PAGER, /* E_CARD_SIMPLE_PHONE_ID_PAGER, */
- E_CARD_PHONE_PREF, /* E_CARD_SIMPLE_PHONE_ID_PRIMARY, */
- E_CARD_PHONE_RADIO, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */
- E_CARD_PHONE_TELEX, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */
- E_CARD_PHONE_TTYTDD, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */
-};
-
-char *phone_names[] = {
- NULL, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */
- "Business",
- "Business 2",
- "Business Fax",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */
- "Car",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */
- "Home",
- "Home 2",
- "Home Fax",
- "ISDN",
- "Mobile",
- "Other",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */
- "Pager",
- "Primary",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */
- NULL, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */
- NULL, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */
-};
-
-char *phone_short_names[] = {
- NULL, /* E_CARD_SIMPLE_PHONE_ID_ASSISTANT, */
- "Bus",
- "Bus 2",
- "Bus Fax",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_CALLBACK, */
- "Car",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_COMPANY, */
- "Home",
- "Home 2",
- "Home Fax",
- "ISDN",
- "Mob",
- "Other",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_OTHER_FAX, */
- "Pag",
- "Prim",
- NULL, /* E_CARD_SIMPLE_PHONE_ID_RADIO, */
- NULL, /* E_CARD_SIMPLE_PHONE_ID_TELEX, */
- NULL, /* E_CARD_SIMPLE_PHONE_ID_TTYTDD, */
-};
-
-ECardAddressFlags addr_correspondences[] = {
- E_CARD_ADDR_WORK, /* E_CARD_SIMPLE_ADDRESS_ID_BUSINESS, */
- E_CARD_ADDR_HOME, /* E_CARD_SIMPLE_ADDRESS_ID_HOME, */
- E_CARD_ADDR_POSTAL, /* E_CARD_SIMPLE_ADDRESS_ID_OTHER, */
-};
-
-char *address_names[] = {
- "Business",
- "Home",
- "Other",
-};
-
-/**
- * e_card_simple_get_type:
- * @void:
- *
- * Registers the &ECardSimple class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &ECardSimple class.
- **/
-GType
-e_card_simple_get_type (void)
-{
- static GType simple_type = 0;
-
- if (!simple_type) {
- static const GTypeInfo simple_info = {
- sizeof (ECardSimpleClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_card_simple_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ECardSimple),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_card_simple_init,
- };
-
- simple_type = g_type_register_static (G_TYPE_OBJECT, "ECardSimple", &simple_info, 0);
- }
-
- return simple_type;
-}
-
-/**
- * e_card_simple_new:
- * @VCard: a string in vCard format
- *
- * Returns: a new #ECardSimple that wraps the @VCard.
- */
-ECardSimple *
-e_card_simple_new (ECard *card)
-{
- ECardSimple *simple = g_object_new (E_TYPE_CARD_SIMPLE, NULL);
- g_object_set(simple,
- "card", card,
- NULL);
- return simple;
-}
-
-ECardSimple *
-e_card_simple_duplicate(ECardSimple *simple)
-{
- ECard *card = simple->card ? e_card_duplicate (simple->card) : e_card_new ("");
- ECardSimple *new_simple = e_card_simple_new(card);
- return new_simple;
-}
-
-/**
- * e_card_simple_get_id:
- * @simple: an #ECardSimple
- *
- * Returns: a string representing the id of the simple, which is unique
- * within its book.
- */
-const char *
-e_card_simple_get_id (ECardSimple *simple)
-{
- if (simple->card)
- return e_card_get_id(simple->card);
- else
- return "";
-}
-
-/**
- * e_card_simple_get_id:
- * @simple: an #ECardSimple
- * @id: a id in string format
- *
- * Sets the identifier of a simple, which should be unique within its
- * book.
- */
-void
-e_card_simple_set_id (ECardSimple *simple, const char *id)
-{
- if ( simple->card )
- e_card_set_id(simple->card, id);
-}
-
-/**
- * e_card_simple_get_vcard:
- * @simple: an #ECardSimple
- *
- * Returns: a string in vcard format, which is wrapped by the @simple.
- */
-char *
-e_card_simple_get_vcard (ECardSimple *simple)
-{
- if (simple->card)
- return e_card_get_vcard(simple->card);
- else
- return g_strdup("");
-}
-
-/**
- * e_card_simple_get_vcard_assume_utf8:
- * @simple: an #ECardSimple
- *
- * Returns: a string in vcard format, which is wrapped by the @simple.
- */
-char *
-e_card_simple_get_vcard_assume_utf8 (ECardSimple *simple)
-{
- if (simple->card)
- return e_card_get_vcard_assume_utf8(simple->card);
- else
- return g_strdup("");
-}
-
-static void
-e_card_simple_class_init (ECardSimpleClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS(klass);
-
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- object_class->dispose = e_card_simple_dispose;
- object_class->get_property = e_card_simple_get_property;
- object_class->set_property = e_card_simple_set_property;
-
- g_object_class_install_property (object_class, PROP_CARD,
- g_param_spec_object ("card",
- _("ECard"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_CARD,
- G_PARAM_READWRITE));
-}
-
-/*
- * ECardSimple lifecycle management and vcard loading/saving.
- */
-
-static void
-e_card_simple_dispose (GObject *object)
-{
- ECardSimple *simple;
- int i;
-
- simple = E_CARD_SIMPLE (object);
-
- if (simple->card) {
- g_object_unref(simple->card);
- simple->card = NULL;
- }
- if (simple->temp_fields) {
- g_list_foreach(simple->temp_fields, (GFunc) g_free, NULL);
- g_list_free(simple->temp_fields);
- simple->temp_fields = NULL;
- }
-
- for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) {
- if (simple->phone[i]) {
- e_card_phone_unref (simple->phone[i]);
- simple->phone[i] = NULL;
- }
- }
- for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) {
- if (simple->email[i]) {
- g_free(simple->email[i]);
- simple->email[i] = NULL;
- }
- }
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- if (simple->address[i]) {
- e_card_address_label_unref(simple->address[i]);
- simple->address[i] = NULL;
- }
- }
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- if (simple->delivery[i]) {
- e_card_delivery_address_unref(simple->delivery[i]);
- simple->delivery[i] = NULL;
- }
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-
-/* Set_arg handler for the simple */
-static void
-e_card_simple_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- ECardSimple *simple;
-
- simple = E_CARD_SIMPLE (object);
-
- switch (prop_id) {
- case PROP_CARD:
- if (simple->card)
- g_object_unref(simple->card);
- g_list_foreach(simple->temp_fields, (GFunc) g_free, NULL);
- g_list_free(simple->temp_fields);
- simple->temp_fields = NULL;
- if (g_value_get_object (value))
- simple->card = E_CARD(g_value_get_object (value));
- else
- simple->card = NULL;
- if(simple->card)
- g_object_ref(simple->card);
- fill_in_info(simple);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* Get_arg handler for the simple */
-static void
-e_card_simple_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- ECardSimple *simple;
-
- simple = E_CARD_SIMPLE (object);
-
- switch (prop_id) {
- case PROP_CARD:
- e_card_simple_sync_card(simple);
- g_value_set_object (value, simple->card);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-/**
- * e_card_simple_init:
- */
-static void
-e_card_simple_init (ECardSimple *simple)
-{
- int i;
- simple->card = NULL;
- for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++)
- simple->phone[i] = NULL;
- for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++)
- simple->email[i] = NULL;
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++)
- simple->address[i] = NULL;
- simple->temp_fields = NULL;
-
- simple->changed = TRUE;
-}
-
-static void
-fill_in_info(ECardSimple *simple)
-{
- ECard *card = simple->card;
- if (card) {
- EList *address_list;
- EList *phone_list;
- EList *email_list;
- EList *delivery_list;
- const ECardPhone *phone;
- const char *email;
- const ECardAddrLabel *address;
- const ECardDeliveryAddress *delivery;
- int i;
-
- EIterator *iterator;
-
- g_object_get(card,
- "address_label", &address_list,
- "address", &delivery_list,
- "phone", &phone_list,
- "email", &email_list,
- NULL);
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) {
- e_card_phone_unref(simple->phone[i]);
- simple->phone[i] = NULL;
- }
- for (iterator = e_list_get_iterator(phone_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- gboolean found = FALSE;
- phone = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- if ((phone->flags == phone_correspondences[i]) && (simple->phone[i] == NULL)) {
- simple->phone[i] = e_card_phone_ref(phone);
- found = TRUE;
- break;
- }
- }
- if (found)
- continue;
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- if (((phone->flags & phone_correspondences[i]) == phone_correspondences[i]) && (simple->phone[i] == NULL)) {
- simple->phone[i] = e_card_phone_ref(phone);
- break;
- }
- }
- }
- g_object_unref(iterator);
-
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) {
- g_free(simple->email[i]);
- simple->email[i] = NULL;
- }
- for (iterator = e_list_get_iterator(email_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- email = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) {
- if ((simple->email[i] == NULL)) {
- simple->email[i] = g_strdup(email);
- break;
- }
- }
- }
- g_object_unref(iterator);
-
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- e_card_address_label_unref(simple->address[i]);
- simple->address[i] = NULL;
- }
- for (iterator = e_list_get_iterator(address_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- address = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if (((address->flags & addr_correspondences[i]) == addr_correspondences[i]) && (simple->address[i] == NULL)) {
- simple->address[i] = e_card_address_label_ref(address);
- break;
- }
- }
- }
- g_object_unref(iterator);
-
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- e_card_delivery_address_unref(simple->delivery[i]);
- simple->delivery[i] = NULL;
- }
- for (iterator = e_list_get_iterator(delivery_list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- delivery = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if (((delivery->flags & addr_correspondences[i]) == addr_correspondences[i]) && (simple->delivery[i] == NULL)) {
- simple->delivery[i] = e_card_delivery_address_ref(delivery);
- break;
- }
- }
- }
- g_object_unref(iterator);
-
- g_object_unref(phone_list);
- g_object_unref(email_list);
- g_object_unref(address_list);
- g_object_unref(delivery_list);
- e_card_free_empty_lists (card);
- }
-}
-
-void
-e_card_simple_sync_card(ECardSimple *simple)
-{
- ECard *card = simple->card;
- if (card && simple->changed) {
- EList *address_list;
- EList *phone_list;
- EList *email_list;
- EList *delivery_list;
- const ECardPhone *phone;
- const ECardAddrLabel *address;
- const ECardDeliveryAddress *delivery;
- const char *email;
- int i;
-
- EIterator *iterator;
-
- g_object_get(card,
- "address_label", &address_list,
- "address", &delivery_list,
- "phone", &phone_list,
- "email", &email_list,
- NULL);
-
- for (iterator = e_list_get_iterator(phone_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) {
- int i;
- gboolean found = FALSE;
- phone = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- if (phone->flags == phone_correspondences[i]) {
- if (simple->phone[i]) {
- simple->phone[i]->flags = phone_correspondences[i];
- if (simple->phone[i]->number && *simple->phone[i]->number) {
- e_iterator_set(iterator, simple->phone[i]);
- } else {
- e_iterator_delete(iterator);
- }
- e_card_phone_unref(simple->phone[i]);
- simple->phone[i] = NULL;
- found = TRUE;
- break;
- }
- }
- }
- if (found)
- continue;
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- if ((phone->flags & phone_correspondences[i]) == phone_correspondences[i]) {
- if (simple->phone[i]) {
- simple->phone[i]->flags = phone_correspondences[i];
- if (simple->phone[i]->number && *simple->phone[i]->number) {
- e_iterator_set(iterator, simple->phone[i]);
- } else {
- e_iterator_delete(iterator);
- }
- e_card_phone_unref(simple->phone[i]);
- simple->phone[i] = NULL;
- break;
- }
- }
- }
- }
- g_object_unref(iterator);
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- if (simple->phone[i]) {
- simple->phone[i]->flags = phone_correspondences[i];
- e_list_append(phone_list, simple->phone[i]);
- e_card_phone_unref(simple->phone[i]);
- simple->phone[i] = NULL;
- }
- }
-
- for (iterator = e_list_get_iterator(email_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) {
- int i;
- email = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) {
- if (simple->email[i]) {
- if (*simple->email[i]) {
- e_iterator_set(iterator, simple->email[i]);
- } else {
- e_iterator_delete(iterator);
- }
- g_free(simple->email[i]);
- simple->email[i] = NULL;
- break;
- }
- }
- }
- g_object_unref(iterator);
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) {
- if (simple->email[i]) {
- e_list_append(email_list, simple->email[i]);
- g_free(simple->email[i]);
- simple->email[i] = NULL;
- }
- }
-
- for (iterator = e_list_get_iterator(address_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) {
- int i;
- address = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if ((address->flags & addr_correspondences[i]) == addr_correspondences[i]) {
- if (simple->address[i]) {
- simple->address[i]->flags &= ~E_CARD_ADDR_MASK;
- simple->address[i]->flags |= addr_correspondences[i];
- if (simple->address[i]->data && *simple->address[i]->data) {
- e_iterator_set(iterator, simple->address[i]);
- } else {
- e_iterator_delete(iterator);
- }
- e_card_address_label_unref(simple->address[i]);
- simple->address[i] = NULL;
- break;
- }
- }
- }
- }
- g_object_unref(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if (simple->address[i]) {
- simple->address[i]->flags &= ~E_CARD_ADDR_MASK;
- simple->address[i]->flags |= addr_correspondences[i];
- e_list_append(address_list, simple->address[i]);
- e_card_address_label_unref(simple->address[i]);
- simple->address[i] = NULL;
- }
- }
-
- for (iterator = e_list_get_iterator(delivery_list); e_iterator_is_valid(iterator); e_iterator_next(iterator) ) {
- int i;
- delivery = e_iterator_get(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if ((delivery->flags & addr_correspondences[i]) == addr_correspondences[i]) {
- if (simple->delivery[i]) {
- simple->delivery[i]->flags &= ~E_CARD_ADDR_MASK;
- simple->delivery[i]->flags |= addr_correspondences[i];
- if (!e_card_delivery_address_is_empty(simple->delivery[i])) {
- e_iterator_set(iterator, simple->delivery[i]);
- } else {
- e_iterator_delete(iterator);
- }
- e_card_delivery_address_unref(simple->delivery[i]);
- simple->delivery[i] = NULL;
- break;
- }
- }
- }
- }
- g_object_unref(iterator);
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
- if (simple->delivery[i]) {
- simple->delivery[i]->flags &= ~E_CARD_ADDR_MASK;
- simple->delivery[i]->flags |= addr_correspondences[i];
- e_list_append(delivery_list, simple->delivery[i]);
- e_card_delivery_address_unref(simple->delivery[i]);
- simple->delivery[i] = NULL;
- }
- }
- fill_in_info(simple);
-
- g_object_unref(phone_list);
- g_object_unref(email_list);
- g_object_unref(address_list);
- g_object_unref(delivery_list);
- e_card_free_empty_lists (card);
- }
-
- simple->changed = FALSE;
-}
-
-const ECardPhone *e_card_simple_get_phone (ECardSimple *simple,
- ECardSimplePhoneId id)
-{
- return simple->phone[id];
-}
-
-const char *e_card_simple_get_email (ECardSimple *simple,
- ECardSimpleEmailId id)
-{
- return simple->email[id];
-}
-
-const ECardAddrLabel *e_card_simple_get_address (ECardSimple *simple,
- ECardSimpleAddressId id)
-{
- return simple->address[id];
-}
-
-const ECardDeliveryAddress *e_card_simple_get_delivery_address (ECardSimple *simple,
- ECardSimpleAddressId id)
-{
- return simple->delivery[id];
-}
-
-void e_card_simple_set_phone (ECardSimple *simple,
- ECardSimplePhoneId id,
- const ECardPhone *phone)
-{
- e_card_phone_unref(simple->phone[id]);
- simple->phone[id] = e_card_phone_ref(phone);
- simple->changed = TRUE;
-}
-
-void e_card_simple_set_email (ECardSimple *simple,
- ECardSimpleEmailId id,
- const char *email)
-{
- g_free(simple->email[id]);
- simple->email[id] = g_strdup(email);
- simple->changed = TRUE;
-}
-
-void
-e_card_simple_set_address (ECardSimple *simple, ECardSimpleAddressId id, const ECardAddrLabel *address)
-{
- e_card_address_label_unref(simple->address[id]);
- simple->address[id] = e_card_address_label_ref(address);
- e_card_delivery_address_unref(simple->delivery[id]);
- simple->delivery[id] = e_card_delivery_address_from_label(simple->address[id]);
- simple->changed = TRUE;
-}
-
-void e_card_simple_set_delivery_address (ECardSimple *simple,
- ECardSimpleAddressId id,
- const ECardDeliveryAddress *delivery)
-{
- e_card_delivery_address_unref(simple->delivery[id]);
- simple->delivery[id] = e_card_delivery_address_ref(delivery);
- e_card_address_label_unref(simple->address[id]);
- simple->address[id] = e_card_delivery_address_to_label(simple->delivery[id]);
- simple->changed = TRUE;
-}
-
-const char *e_card_simple_get_const (ECardSimple *simple,
- ECardSimpleField field)
-{
- char *ret_val = e_card_simple_get(simple, field);
- if (ret_val)
- simple->temp_fields = g_list_prepend(simple->temp_fields, ret_val);
- return ret_val;
-}
-
-char *e_card_simple_get (ECardSimple *simple,
- ECardSimpleField field)
-{
- ECardSimpleInternalType type = field_data[field].type;
- const ECardAddrLabel *addr;
- const ECardPhone *phone;
- char *string;
- ECardDate *date;
- ECardName *name;
- switch(type) {
- case E_CARD_SIMPLE_INTERNAL_TYPE_STRING:
- if (simple->card) {
- g_object_get(simple->card,
- field_data[field].ecard_field, &string,
- NULL);
- return string;
- } else
- return NULL;
- case E_CARD_SIMPLE_INTERNAL_TYPE_DATE:
- if (simple->card) {
- g_object_get(simple->card,
- field_data[field].ecard_field, &date,
- NULL);
- if (date != NULL) {
- char buf[26];
- struct tm then;
- then.tm_year = date->year;
- then.tm_mon = date->month - 1;
- then.tm_mday = date->day;
- then.tm_hour = 12;
- then.tm_min = 0;
- then.tm_sec = 0;
- e_strftime_fix_am_pm (buf, 26, _("%x"), &then);
- return g_strdup (buf);
- } else {
- return NULL;
- }
- } else
- return NULL;
- case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS:
- addr = e_card_simple_get_address(simple,
- field_data[field].list_type_index);
- if (addr)
- return g_strdup(addr->data);
- else
- return NULL;
- case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE:
- phone = e_card_simple_get_phone(simple,
- field_data[field].list_type_index);
- if (phone)
- return g_strdup(phone->number);
- else
- return NULL;
- case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL:
- string = e_card_simple_get_email(simple,
- field_data[field].list_type_index);
- return g_strdup(string);
- case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL:
- if (simple->card) {
- gboolean boole;
- g_object_get (simple->card,
- field_data[field].ecard_field, &boole,
- NULL);
- if (boole)
- return g_strdup("true");
- else
- return NULL;
- } else {
- return NULL;
- }
- case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL:
- switch (field) {
- case E_CARD_SIMPLE_FIELD_NAME_OR_ORG:
- if (simple->card) {
- gboolean is_list;
-
- g_object_get(simple->card,
- "file_as", &string,
- NULL);
- if (string && *string)
- return string
-; else
- g_free (string);
-
- g_object_get(simple->card,
- "full_name", &string,
- NULL);
- if (string && *string)
- return g_strdup(string);
- else
- g_free (string);
-
- g_object_get(simple->card,
- "org", &string,
- NULL);
- if (string && *string)
- return g_strdup(string);
- else
- g_free (string);
-
- is_list = e_card_evolution_list (simple->card);
- if (is_list)
- string = _("Unnamed List");
- else
- string = e_card_simple_get_email(simple,
- E_CARD_SIMPLE_EMAIL_ID_EMAIL);
- return g_strdup(string);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_FAMILY_NAME:
- if (simple->card) {
- g_object_get (simple->card,
- "name", &name,
- NULL);
- return g_strdup (name->family);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_GIVEN_NAME:
- if (simple->card) {
- g_object_get (simple->card,
- "name", &name,
- NULL);
- return g_strdup (name->given);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME:
- if (simple->card) {
- g_object_get (simple->card,
- "name", &name,
- NULL);
- return g_strdup (name->additional);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_NAME_SUFFIX:
- if (simple->card) {
- g_object_get (simple->card,
- "name", &name,
- NULL);
- return g_strdup (name->suffix);
- } else
- return NULL;
- default:
- return NULL;
- }
- default:
- return NULL;
- }
-}
-
-static char *
-name_to_style(const ECardName *name, char *company, int style)
-{
- char *string;
- char *strings[4], **stringptr;
- char *substring;
- switch (style) {
- case 0:
- stringptr = strings;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- *stringptr = NULL;
- string = g_strjoinv(", ", strings);
- break;
- case 1:
- stringptr = strings;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- *stringptr = NULL;
- string = g_strjoinv(" ", strings);
- break;
- case 2:
- string = g_strdup(company);
- break;
- case 3: /* Fall Through */
- case 4:
- stringptr = strings;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- *stringptr = NULL;
- substring = g_strjoinv(", ", strings);
- if (!(company && *company))
- company = "";
- if (style == 3)
- string = g_strdup_printf("%s (%s)", substring, company);
- else
- string = g_strdup_printf("%s (%s)", company, substring);
- g_free(substring);
- break;
- default:
- string = g_strdup("");
- }
- return string;
-}
-
-static int
-file_as_get_style (ECardSimple *simple)
-{
- char *filestring = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- char *trystring;
- char *company = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_ORG);
- ECardName *name = NULL;
- int i;
- int style;
- style = 0;
- if (!company)
- company = g_strdup("");
- if (filestring) {
- g_object_get (simple->card,
- "name", &name,
- NULL);
-
- if (!name) {
- goto end;
- }
-
- style = -1;
-
- for (i = 0; i < 5; i++) {
- trystring = name_to_style(name, company, i);
- if (!strcmp(trystring, filestring)) {
- g_free(trystring);
- style = i;
- goto end;
- }
- g_free(trystring);
- }
- }
- end:
-
- g_free(filestring);
- g_free(company);
-
- return style;
-}
-
-static void
-file_as_set_style(ECardSimple *simple, int style)
-{
- if (style != -1) {
- char *string;
- char *company = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_ORG);
- ECardName *name;
-
- if (!company)
- company = g_strdup("");
- g_object_get (simple->card,
- "name", &name,
- NULL);
- if (name) {
- string = name_to_style(name, company, style);
- e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_FILE_AS, string);
- g_free(string);
- }
- g_free(company);
- }
-}
-
-void e_card_simple_set (ECardSimple *simple,
- ECardSimpleField field,
- const char *data)
-{
- ECardSimpleInternalType type = field_data[field].type;
- ECardAddrLabel *address;
- ECardPhone *phone;
- int style;
- simple->changed = TRUE;
- switch (field) {
- case E_CARD_SIMPLE_FIELD_FULL_NAME:
- case E_CARD_SIMPLE_FIELD_ORG:
- style = file_as_get_style(simple);
- g_object_set(simple->card,
- field_data[field].ecard_field, data,
- NULL);
- file_as_set_style(simple, style);
- break;
- default:
- switch(type) {
- case E_CARD_SIMPLE_INTERNAL_TYPE_STRING:
- g_object_set(simple->card,
- field_data[field].ecard_field, data,
- NULL);
- break;
- case E_CARD_SIMPLE_INTERNAL_TYPE_DATE:
- break; /* FIXME!!!! */
- case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS:
- address = e_card_address_label_new();
- address->data = g_strdup (data);
- e_card_simple_set_address(simple,
- field_data[field].list_type_index,
- address);
- e_card_address_label_unref(address);
- break;
- case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE:
- phone = e_card_phone_new();
- phone->number = g_strdup (data);
- e_card_simple_set_phone(simple,
- field_data[field].list_type_index,
- phone);
- e_card_phone_unref(phone);
- break;
- case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL:
- e_card_simple_set_email(simple,
- field_data[field].list_type_index,
- data);
- break;
- case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL:
- break;
- case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL:
- if (simple->card) {
- gboolean boole = TRUE;
- if (data == NULL)
- boole = FALSE;
- else if (!strcasecmp (data, "false"))
- boole = FALSE;
- g_object_set (simple->card,
- field_data[field].ecard_field, boole,
- NULL);
- }
- break;
- }
- break;
- }
-}
-
-ECardSimpleType e_card_simple_type (ECardSimple *simple,
- ECardSimpleField field)
-{
- ECardSimpleInternalType type = field_data[field].type;
- switch(type) {
- case E_CARD_SIMPLE_INTERNAL_TYPE_STRING:
- case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS:
- case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE:
- case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL:
- default:
- return E_CARD_SIMPLE_TYPE_STRING;
-
- case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL:
- return E_CARD_SIMPLE_TYPE_BOOL;
-
- case E_CARD_SIMPLE_INTERNAL_TYPE_DATE:
- return E_CARD_SIMPLE_TYPE_DATE;
-
- case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL:
- return E_CARD_SIMPLE_TYPE_STRING;
- }
-}
-
-const char *e_card_simple_get_ecard_field (ECardSimple *simple,
- ECardSimpleField field)
-{
- return field_data[field].ecard_field;
-}
-
-const char *e_card_simple_get_name (ECardSimple *simple,
- ECardSimpleField field)
-{
- return _(field_data[field].name);
-}
-
-gboolean
-e_card_simple_get_allow_newlines (ECardSimple *simple,
- ECardSimpleField field)
-{
- ECardSimpleInternalType type = field_data[field].type;
- switch(type) {
- case E_CARD_SIMPLE_INTERNAL_TYPE_STRING:
- case E_CARD_SIMPLE_INTERNAL_TYPE_PHONE:
- case E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL:
- case E_CARD_SIMPLE_INTERNAL_TYPE_BOOL:
- case E_CARD_SIMPLE_INTERNAL_TYPE_DATE:
- case E_CARD_SIMPLE_INTERNAL_TYPE_SPECIAL:
- default:
- switch (field) {
- case E_CARD_SIMPLE_FIELD_NOTE:
- return TRUE;
- default:
- return FALSE;
- }
-
- case E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS:
- return TRUE;
- }
-}
-
-const char *e_card_simple_get_short_name (ECardSimple *simple,
- ECardSimpleField field)
-{
- return _(field_data[field].short_name);
-}
-
-void e_card_simple_arbitrary_foreach (ECardSimple *simple,
- ECardSimpleArbitraryCallback *callback,
- gpointer closure)
-{
- if (simple->card) {
- EList *list;
- EIterator *iterator;
- g_object_get(simple->card,
- "arbitrary", &list,
- NULL);
- for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get(iterator);
- if (callback)
- (*callback) (arbitrary, closure);
- }
-
- g_object_unref (list);
- e_card_free_empty_lists (simple->card);
- }
-}
-
-const ECardArbitrary *e_card_simple_get_arbitrary (ECardSimple *simple,
- const char *key)
-{
- if (simple->card) {
- EList *list;
- EIterator *iterator;
- g_object_get(simple->card,
- "arbitrary", &list,
- NULL);
- for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get(iterator);
- if (!strcasecmp(arbitrary->key, key))
- return arbitrary;
- }
-
- g_object_unref (list);
- e_card_free_empty_lists (simple->card);
- }
- return NULL;
-}
-
-/* Any of these except key can be NULL */
-void e_card_simple_set_arbitrary (ECardSimple *simple,
- const char *key,
- const char *type,
- const char *value)
-{
- if (simple->card) {
- ECardArbitrary *new_arb;
- EList *list;
- EIterator *iterator;
-
- simple->changed = TRUE;
- g_object_get(simple->card,
- "arbitrary", &list,
- NULL);
- for (iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get(iterator);
- if (!strcasecmp(arbitrary->key, key)) {
- new_arb = e_card_arbitrary_new();
- new_arb->key = g_strdup(key);
- new_arb->type = g_strdup(type);
- new_arb->value = g_strdup(value);
- e_iterator_set(iterator, new_arb);
- e_card_arbitrary_unref(new_arb);
- return;
- }
- }
- new_arb = e_card_arbitrary_new();
- new_arb->key = g_strdup(key);
- new_arb->type = g_strdup(type);
- new_arb->value = g_strdup(value);
- e_list_append(list, new_arb);
- g_object_unref(list);
- e_card_arbitrary_unref(new_arb);
- }
-}
-
-void
-e_card_simple_set_name (ECardSimple *simple, ECardName *name)
-{
- int style;
- style = file_as_get_style(simple);
- g_object_set (simple->card,
- "name", name,
- NULL);
- file_as_set_style(simple, style);
-}
-
-/* These map between the individual list types and ECardSimpleField */
-ECardSimpleField
-e_card_simple_map_phone_to_field (ECardSimplePhoneId phone_id)
-{
- int i;
-
- g_return_val_if_fail (phone_id < E_CARD_SIMPLE_PHONE_ID_LAST, 0);
-
- for (i = 0; i < field_data_count; i ++)
- if (field_data[i].list_type_index == phone_id
- && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_PHONE)
- return i;
-
- g_warning ("couldn't find phone id %d, returning 0 (which is almost assuredly incorrect)\n", phone_id);
-
- return 0;
-}
-
-ECardSimpleField
-e_card_simple_map_email_to_field (ECardSimpleEmailId email_id)
-{
- int i;
-
- g_return_val_if_fail (email_id < E_CARD_SIMPLE_EMAIL_ID_LAST, 0);
-
- for (i = 0; i < field_data_count; i ++)
- if (field_data[i].list_type_index == email_id
- && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_EMAIL)
- return i;
-
- g_warning ("couldn't find email id %d, returning 0 (which is almost assuredly incorrect)\n", email_id);
- return 0;
-}
-
-ECardSimpleField
-e_card_simple_map_address_to_field (ECardSimpleAddressId address_id)
-{
- int i;
-
- g_return_val_if_fail (address_id < E_CARD_SIMPLE_ADDRESS_ID_LAST, 0);
-
- for (i = 0; i < field_data_count; i ++)
- if (field_data[i].list_type_index == address_id
- && field_data[i].type == E_CARD_SIMPLE_INTERNAL_TYPE_ADDRESS)
- return i;
-
- g_warning ("couldn't find address id %d, returning 0 (which is almost assuredly incorrect)\n", address_id);
- return 0;
-}
diff --git a/addressbook/backend/ebook/e-card-simple.h b/addressbook/backend/ebook/e-card-simple.h
deleted file mode 100644
index 868d4e1573..0000000000
--- a/addressbook/backend/ebook/e-card-simple.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Arturo Espinosa
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 1999 The Free Software Foundation
- */
-
-#ifndef __E_CARD_SIMPLE_H__
-#define __E_CARD_SIMPLE_H__
-
-#include <time.h>
-#include <glib-object.h>
-#include <stdio.h>
-#include <ebook/e-card.h>
-#include <ebook/e-card-types.h>
-#include <e-util/e-list.h>
-
-#define E_TYPE_CARD_SIMPLE (e_card_simple_get_type ())
-#define E_CARD_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CARD_SIMPLE, ECardSimple))
-#define E_CARD_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_SIMPLE, ECardSimpleClass))
-#define E_IS_CARD_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CARD_SIMPLE))
-#define E_IS_CARD_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_SIMPLE))
-#define E_CARD_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD_SIMPLE, ECardSimpleClass))
-
-typedef enum _ECardSimplePhoneId ECardSimplePhoneId;
-typedef enum _ECardSimpleEmailId ECardSimpleEmailId;
-typedef enum _ECardSimpleAddressId ECardSimpleAddressId;
-typedef enum _ECardSimpleType ECardSimpleType;
-typedef enum _ECardSimpleField ECardSimpleField;
-
-enum _ECardSimplePhoneId {
- E_CARD_SIMPLE_PHONE_ID_ASSISTANT,
- E_CARD_SIMPLE_PHONE_ID_BUSINESS,
- E_CARD_SIMPLE_PHONE_ID_BUSINESS_2,
- E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX,
- E_CARD_SIMPLE_PHONE_ID_CALLBACK,
- E_CARD_SIMPLE_PHONE_ID_CAR,
- E_CARD_SIMPLE_PHONE_ID_COMPANY,
- E_CARD_SIMPLE_PHONE_ID_HOME,
- E_CARD_SIMPLE_PHONE_ID_HOME_2,
- E_CARD_SIMPLE_PHONE_ID_HOME_FAX,
- E_CARD_SIMPLE_PHONE_ID_ISDN,
- E_CARD_SIMPLE_PHONE_ID_MOBILE,
- E_CARD_SIMPLE_PHONE_ID_OTHER,
- E_CARD_SIMPLE_PHONE_ID_OTHER_FAX,
- E_CARD_SIMPLE_PHONE_ID_PAGER,
- E_CARD_SIMPLE_PHONE_ID_PRIMARY,
- E_CARD_SIMPLE_PHONE_ID_RADIO,
- E_CARD_SIMPLE_PHONE_ID_TELEX,
- E_CARD_SIMPLE_PHONE_ID_TTYTDD,
- E_CARD_SIMPLE_PHONE_ID_LAST
-};
-
-/* We need HOME and WORK email addresses here. */
-enum _ECardSimpleEmailId {
- E_CARD_SIMPLE_EMAIL_ID_EMAIL,
- E_CARD_SIMPLE_EMAIL_ID_EMAIL_2,
- E_CARD_SIMPLE_EMAIL_ID_EMAIL_3,
- E_CARD_SIMPLE_EMAIL_ID_LAST
-};
-
-/* Should this include (BILLING/SHIPPING)? */
-enum _ECardSimpleAddressId {
- E_CARD_SIMPLE_ADDRESS_ID_BUSINESS,
- E_CARD_SIMPLE_ADDRESS_ID_HOME,
- E_CARD_SIMPLE_ADDRESS_ID_OTHER,
- E_CARD_SIMPLE_ADDRESS_ID_LAST
-};
-
-enum _ECardSimpleType {
- E_CARD_SIMPLE_TYPE_STRING,
- E_CARD_SIMPLE_TYPE_DATE,
- E_CARD_SIMPLE_TYPE_BOOL,
-};
-
-enum _ECardSimpleField {
- E_CARD_SIMPLE_FIELD_FILE_AS,
- E_CARD_SIMPLE_FIELD_FULL_NAME,
- E_CARD_SIMPLE_FIELD_EMAIL,
- E_CARD_SIMPLE_FIELD_PHONE_PRIMARY,
- E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT,
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS,
- E_CARD_SIMPLE_FIELD_PHONE_CALLBACK,
- E_CARD_SIMPLE_FIELD_PHONE_COMPANY,
- E_CARD_SIMPLE_FIELD_PHONE_HOME,
- E_CARD_SIMPLE_FIELD_ORG,
- E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS,
- E_CARD_SIMPLE_FIELD_ADDRESS_HOME,
- E_CARD_SIMPLE_FIELD_PHONE_MOBILE,
- E_CARD_SIMPLE_FIELD_PHONE_CAR,
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX,
- E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX,
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2,
- E_CARD_SIMPLE_FIELD_PHONE_HOME_2,
- E_CARD_SIMPLE_FIELD_PHONE_ISDN,
- E_CARD_SIMPLE_FIELD_PHONE_OTHER,
- E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX,
- E_CARD_SIMPLE_FIELD_PHONE_PAGER,
- E_CARD_SIMPLE_FIELD_PHONE_RADIO,
- E_CARD_SIMPLE_FIELD_PHONE_TELEX,
- E_CARD_SIMPLE_FIELD_PHONE_TTYTDD,
- E_CARD_SIMPLE_FIELD_ADDRESS_OTHER,
- E_CARD_SIMPLE_FIELD_EMAIL_2,
- E_CARD_SIMPLE_FIELD_EMAIL_3,
- E_CARD_SIMPLE_FIELD_URL,
- E_CARD_SIMPLE_FIELD_ORG_UNIT,
- E_CARD_SIMPLE_FIELD_OFFICE,
- E_CARD_SIMPLE_FIELD_TITLE,
- E_CARD_SIMPLE_FIELD_ROLE,
- E_CARD_SIMPLE_FIELD_MANAGER,
- E_CARD_SIMPLE_FIELD_ASSISTANT,
- E_CARD_SIMPLE_FIELD_NICKNAME,
- E_CARD_SIMPLE_FIELD_SPOUSE,
- E_CARD_SIMPLE_FIELD_NOTE,
- E_CARD_SIMPLE_FIELD_CALURI,
- E_CARD_SIMPLE_FIELD_FBURL,
- E_CARD_SIMPLE_FIELD_ICSCALENDAR,
- /* If you add after icscalendar, make sure to move LAST_SIMPLE_STRING */
- E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING = E_CARD_SIMPLE_FIELD_ICSCALENDAR,
- E_CARD_SIMPLE_FIELD_ANNIVERSARY,
- E_CARD_SIMPLE_FIELD_BIRTH_DATE,
- E_CARD_SIMPLE_FIELD_MAILER,
- E_CARD_SIMPLE_FIELD_NAME_OR_ORG,
- E_CARD_SIMPLE_FIELD_CATEGORIES,
- E_CARD_SIMPLE_FIELD_FAMILY_NAME,
- E_CARD_SIMPLE_FIELD_GIVEN_NAME,
- E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME,
- E_CARD_SIMPLE_FIELD_NAME_SUFFIX,
- E_CARD_SIMPLE_FIELD_WANTS_HTML,
- E_CARD_SIMPLE_FIELD_IS_LIST,
- E_CARD_SIMPLE_FIELD_LAST
-};
-
-typedef struct _ECardSimple ECardSimple;
-typedef struct _ECardSimpleClass ECardSimpleClass;
-
-struct _ECardSimple {
- GObject object;
- ECard *card;
-
- GList *temp_fields;
-
- ECardPhone *phone[E_CARD_SIMPLE_PHONE_ID_LAST];
- char *email[E_CARD_SIMPLE_EMAIL_ID_LAST];
- ECardAddrLabel *address[E_CARD_SIMPLE_ADDRESS_ID_LAST];
- ECardDeliveryAddress *delivery[E_CARD_SIMPLE_ADDRESS_ID_LAST];
-
- gboolean changed;
-};
-
-struct _ECardSimpleClass {
- GObjectClass parent_class;
-};
-
-typedef void (*ECardSimpleArbitraryCallback) (const ECardArbitrary *arbitrary, gpointer closure);
-ECardSimple *e_card_simple_new (ECard *card);
-const char *e_card_simple_get_id (ECardSimple *simple);
-void e_card_simple_set_id (ECardSimple *simple,
- const gchar *character);
-char *e_card_simple_get_vcard (ECardSimple *simple);
-char *e_card_simple_get_vcard_assume_utf8 (ECardSimple *simple);
-ECardSimple *e_card_simple_duplicate (ECardSimple *simple);
-char *e_card_simple_get (ECardSimple *simple,
- ECardSimpleField field);
-const char *e_card_simple_get_const (ECardSimple *simple,
- ECardSimpleField field);
-void e_card_simple_set (ECardSimple *simple,
- ECardSimpleField field,
- const char *data);
-ECardSimpleType e_card_simple_type (ECardSimple *simple,
- ECardSimpleField field);
-
-const char *e_card_simple_get_ecard_field (ECardSimple *simple,
- ECardSimpleField field);
-const char *e_card_simple_get_name (ECardSimple *simple,
- ECardSimpleField field);
-const char *e_card_simple_get_short_name (ECardSimple *simple,
- ECardSimpleField field);
-gboolean e_card_simple_get_allow_newlines (ECardSimple *simple,
- ECardSimpleField field);
-
-
-/* Use these only if building lists of specific types. It should be
- * easier to use the above if you consider a phone field to be the
- * same as any other field.
- */
-const ECardPhone *e_card_simple_get_phone (ECardSimple *simple,
- ECardSimplePhoneId id);
-const char *e_card_simple_get_email (ECardSimple *simple,
- ECardSimpleEmailId id);
-const ECardAddrLabel *e_card_simple_get_address (ECardSimple *simple,
- ECardSimpleAddressId id);
-const ECardDeliveryAddress *e_card_simple_get_delivery_address (ECardSimple *simple,
- ECardSimpleAddressId id);
-void e_card_simple_set_phone (ECardSimple *simple,
- ECardSimplePhoneId id,
- const ECardPhone *phone);
-void e_card_simple_set_email (ECardSimple *simple,
- ECardSimpleEmailId id,
- const char *email);
-void e_card_simple_set_address (ECardSimple *simple,
- ECardSimpleAddressId id,
- const ECardAddrLabel *address);
-void e_card_simple_set_delivery_address (ECardSimple *simple,
- ECardSimpleAddressId id,
- const ECardDeliveryAddress *delivery);
-void e_card_simple_arbitrary_foreach (ECardSimple *simple,
- ECardSimpleArbitraryCallback *callback,
- gpointer closure);
-const ECardArbitrary *e_card_simple_get_arbitrary (ECardSimple *simple,
- const char *key);
-/* Any of these except key can be NULL */
-void e_card_simple_set_arbitrary (ECardSimple *simple,
- const char *key,
- const char *type,
- const char *value);
-void e_card_simple_set_name (ECardSimple *simple,
- ECardName *name);
-void e_card_simple_sync_card (ECardSimple *simple);
-
-/* These map between the individual list types and ECardSimpleField */
-ECardSimpleField e_card_simple_map_phone_to_field (ECardSimplePhoneId phone_id);
-ECardSimpleField e_card_simple_map_email_to_field (ECardSimpleEmailId email_id);
-ECardSimpleField e_card_simple_map_address_to_field (ECardSimpleAddressId address_id);
-
-GType e_card_simple_get_type (void);
-
-#endif /* ! __E_CARD_SIMPLE_H__ */
-
-
diff --git a/addressbook/backend/ebook/e-card-types.h b/addressbook/backend/ebook/e-card-types.h
deleted file mode 100644
index 8d35c54924..0000000000
--- a/addressbook/backend/ebook/e-card-types.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Arturo Espinosa
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 1999 The Free Software Foundation
- */
-
-#ifndef __E_CARD_TYPES_H__
-#define __E_CARD_TYPES_H__
-
-/* IDENTIFICATION PROPERTIES */
-
-typedef struct {
- gint ref_count;
- char *prefix; /* Mr. */
- char *given; /* John */
- char *additional; /* Quinlan */
- char *family; /* Public */
- char *suffix; /* Esq. */
-} ECardName;
-
-typedef struct {
- int year;
- int month;
- int day;
-} ECardDate;
-
-/* TELECOMMUNICATIONS ADDRESSING PROPERTIES */
-
-typedef enum {
- E_CARD_PHONE_PREF = 1 << 0,
- E_CARD_PHONE_WORK = 1 << 1,
- E_CARD_PHONE_HOME = 1 << 2,
- E_CARD_PHONE_VOICE = 1 << 3,
- E_CARD_PHONE_FAX = 1 << 4,
- E_CARD_PHONE_MSG = 1 << 5,
- E_CARD_PHONE_CELL = 1 << 6,
- E_CARD_PHONE_PAGER = 1 << 7,
- E_CARD_PHONE_BBS = 1 << 8,
- E_CARD_PHONE_MODEM = 1 << 9,
- E_CARD_PHONE_CAR = 1 << 10,
- E_CARD_PHONE_ISDN = 1 << 11,
- E_CARD_PHONE_VIDEO = 1 << 12,
- E_CARD_PHONE_ASSISTANT = 1 << 13,
- E_CARD_PHONE_CALLBACK = 1 << 14,
- E_CARD_PHONE_RADIO = 1 << 15,
- E_CARD_PHONE_TELEX = 1 << 16,
- E_CARD_PHONE_TTYTDD = 1 << 17,
-} ECardPhoneFlags;
-
-typedef struct {
- gint ref_count;
- ECardPhoneFlags flags;
- char *number;
-} ECardPhone;
-
-/* DELIVERY ADDRESSING PROPERTIES */
-
-typedef enum {
- E_CARD_ADDR_HOME = 1 << 0,
- E_CARD_ADDR_WORK = 1 << 1,
- E_CARD_ADDR_POSTAL = 1 << 2,
- E_CARD_ADDR_MASK = 7,
- E_CARD_ADDR_PARCEL = 1 << 3,
- E_CARD_ADDR_DOM = 1 << 4,
- E_CARD_ADDR_INTL = 1 << 5,
- E_CARD_ADDR_DEFAULT = 1 << 6
-} ECardAddressFlags;
-
-typedef struct {
- gint ref_count;
- ECardAddressFlags flags;
-
- char *po;
- char *ext;
- char *street;
- char *city;
- char *region;
- char *code;
- char *country;
-} ECardDeliveryAddress;
-
-typedef struct {
- gint ref_count;
- ECardAddressFlags flags;
- char *data;
-} ECardAddrLabel;
-
-/* ARBITRARY PROPERTIES */
-
-typedef struct {
- gint ref_count;
- char *key;
- char *type;
- char *value;
-} ECardArbitrary;
-
-#endif /* __E_CARD_TYPES_H__ */
diff --git a/addressbook/backend/ebook/e-card.c b/addressbook/backend/ebook/e-card.c
deleted file mode 100644
index 1b3bbfba88..0000000000
--- a/addressbook/backend/ebook/e-card.c
+++ /dev/null
@@ -1,2807 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Arturo Espinosa (arturo@nuclecu.unam.mx)
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 1999 The Free Software Foundation
- */
-
-#include <config.h>
-
-#include "e-card.h"
-
-#include <gal/widgets/e-unicode.h>
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <math.h>
-
-#include <bonobo/bonobo-i18n.h>
-#include <gal/util/e-util.h>
-
-#include <libversit/vcc.h>
-#include "e-util/ename/e-name-western.h"
-#include "e-util/ename/e-address-western.h"
-#include "e-book.h"
-
-#define is_a_prop_of(obj,prop) (isAPropertyOf ((obj),(prop)))
-#define str_val(obj) (the_str = (vObjectValueType (obj))? fakeCString (vObjectUStringZValue (obj)) : calloc (1, 1))
-#define has(obj,prop) (vo = isAPropertyOf ((obj), (prop)))
-
-#define XEV_WANTS_HTML "X-MOZILLA-HTML"
-#define XEV_ARBITRARY "X-EVOLUTION-ARBITRARY"
-#define XEV_LIST "X-EVOLUTION-LIST"
-#define XEV_LIST_SHOW_ADDRESSES "X-EVOLUTION-LIST-SHOW_ADDRESSES"
-#define XEV_RELATED_CONTACTS "X-EVOLUTION-RELATED_CONTACTS"
-
-/* Object property IDs */
-enum {
- PROP_0,
- PROP_FILE_AS,
- PROP_FULL_NAME,
- PROP_NAME,
- PROP_ADDRESS,
- PROP_ADDRESS_LABEL,
- PROP_PHONE,
- PROP_EMAIL,
- PROP_BIRTH_DATE,
- PROP_URL,
- PROP_ORG,
- PROP_ORG_UNIT,
- PROP_OFFICE,
- PROP_TITLE,
- PROP_ROLE,
- PROP_MANAGER,
- PROP_ASSISTANT,
- PROP_NICKNAME,
- PROP_SPOUSE,
- PROP_ANNIVERSARY,
- PROP_MAILER,
- PROP_CALURI,
- PROP_FBURL,
- PROP_ICSCALENDAR,
- PROP_NOTE,
- PROP_RELATED_CONTACTS,
- PROP_CATEGORIES,
- PROP_CATEGORY_LIST,
- PROP_WANTS_HTML,
- PROP_WANTS_HTML_SET,
- PROP_EVOLUTION_LIST,
- PROP_EVOLUTION_LIST_SHOW_ADDRESSES,
- PROP_ARBITRARY,
- PROP_ID,
- PROP_LAST_USE,
- PROP_USE_SCORE,
-};
-
-static GObjectClass *parent_class;
-
-static void parse(ECard *card, VObject *vobj, const char *default_charset);
-static void e_card_init (ECard *card);
-static void e_card_class_init (ECardClass *klass);
-
-static void e_card_dispose (GObject *object);
-static void e_card_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_card_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-
-static void assign_string(VObject *vobj, const char *default_charset, char **string);
-
-char *e_v_object_get_child_value(VObject *vobj, char *name, const char *default_charset);
-
-static void parse_bday(ECard *card, VObject *object, const char *default_charset);
-static void parse_full_name(ECard *card, VObject *object, const char *default_charset);
-static void parse_file_as(ECard *card, VObject *object, const char *default_charset);
-static void parse_name(ECard *card, VObject *object, const char *default_charset);
-static void parse_email(ECard *card, VObject *object, const char *default_charset);
-static void parse_phone(ECard *card, VObject *object, const char *default_charset);
-static void parse_address(ECard *card, VObject *object, const char *default_charset);
-static void parse_address_label(ECard *card, VObject *object, const char *default_charset);
-static void parse_url(ECard *card, VObject *object, const char *default_charset);
-static void parse_org(ECard *card, VObject *object, const char *default_charset);
-static void parse_office(ECard *card, VObject *object, const char *default_charset);
-static void parse_title(ECard *card, VObject *object, const char *default_charset);
-static void parse_role(ECard *card, VObject *object, const char *default_charset);
-static void parse_manager(ECard *card, VObject *object, const char *default_charset);
-static void parse_assistant(ECard *card, VObject *object, const char *default_charset);
-static void parse_nickname(ECard *card, VObject *object, const char *default_charset);
-static void parse_spouse(ECard *card, VObject *object, const char *default_charset);
-static void parse_anniversary(ECard *card, VObject *object, const char *default_charset);
-static void parse_mailer(ECard *card, VObject *object, const char *default_charset);
-static void parse_caluri(ECard *card, VObject *object, const char *default_charset);
-static void parse_fburl(ECard *card, VObject *object, const char *default_charset);
-static void parse_icscalendar(ECard *card, VObject *object, const char *default_charset);
-static void parse_note(ECard *card, VObject *object, const char *default_charset);
-static void parse_related_contacts(ECard *card, VObject *object, const char *default_charset);
-static void parse_categories(ECard *card, VObject *object, const char *default_charset);
-static void parse_wants_html(ECard *card, VObject *object, const char *default_charset);
-static void parse_list(ECard *card, VObject *object, const char *default_charset);
-static void parse_list_show_addresses(ECard *card, VObject *object, const char *default_charset);
-static void parse_arbitrary(ECard *card, VObject *object, const char *default_charset);
-static void parse_id(ECard *card, VObject *object, const char *default_charset);
-static void parse_last_use(ECard *card, VObject *object, const char *default_charset);
-static void parse_use_score(ECard *card, VObject *object, const char *default_charset);
-
-static ECardPhoneFlags get_phone_flags (VObject *vobj);
-static void set_phone_flags (VObject *vobj, ECardPhoneFlags flags);
-static ECardAddressFlags get_address_flags (VObject *vobj);
-static void set_address_flags (VObject *vobj, ECardAddressFlags flags);
-
-typedef void (* ParsePropertyFunc) (ECard *card, VObject *object, const char *default_charset);
-
-struct {
- char *key;
- ParsePropertyFunc function;
-} attribute_jump_array[] =
-{
- { VCFullNameProp, parse_full_name },
- { "X-EVOLUTION-FILE-AS", parse_file_as },
- { VCNameProp, parse_name },
- { VCBirthDateProp, parse_bday },
- { VCEmailAddressProp, parse_email },
- { VCTelephoneProp, parse_phone },
- { VCAdrProp, parse_address },
- { VCDeliveryLabelProp, parse_address_label },
- { VCURLProp, parse_url },
- { VCOrgProp, parse_org },
- { "X-EVOLUTION-OFFICE", parse_office },
- { VCTitleProp, parse_title },
- { VCBusinessRoleProp, parse_role },
- { "X-EVOLUTION-MANAGER", parse_manager },
- { "X-EVOLUTION-ASSISTANT", parse_assistant },
- { "NICKNAME", parse_nickname },
- { "X-EVOLUTION-SPOUSE", parse_spouse },
- { "X-EVOLUTION-ANNIVERSARY", parse_anniversary },
- { VCMailerProp, parse_mailer },
- { "CALURI", parse_caluri },
- { "FBURL", parse_fburl },
- { "ICSCALENDAR", parse_icscalendar },
- { VCNoteProp, parse_note },
- { XEV_RELATED_CONTACTS, parse_related_contacts },
- { "CATEGORIES", parse_categories },
- { XEV_WANTS_HTML, parse_wants_html },
- { XEV_ARBITRARY, parse_arbitrary },
- { VCUniqueStringProp, parse_id },
- { "X-EVOLUTION-LAST-USE", parse_last_use },
- { "X-EVOLUTION-USE-SCORE", parse_use_score },
- { XEV_LIST, parse_list },
- { XEV_LIST_SHOW_ADDRESSES, parse_list_show_addresses },
- { VCUniqueStringProp, parse_id }
-};
-
-/**
- * e_card_get_type:
- * @void:
- *
- * Registers the &ECard class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &ECard class.
- **/
-GType
-e_card_get_type (void)
-{
- static GType card_type = 0;
-
- if (!card_type) {
- static const GTypeInfo card_info = {
- sizeof (ECardClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_card_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ECard),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_card_init,
- };
-
- card_type = g_type_register_static (G_TYPE_OBJECT, "ECard", &card_info, 0);
- }
-
- return card_type;
-}
-
-ECard *
-e_card_new_with_default_charset (const char *vcard, const char *default_charset)
-{
- ECard *card = g_object_new (E_TYPE_CARD, NULL);
- VObject *vobj = Parse_MIME(vcard, strlen(vcard));
- while(vobj) {
- VObject *next;
- parse(card, vobj, default_charset);
- next = nextVObjectInList(vobj);
- cleanVObject(vobj);
- vobj = next;
- }
- if (card->name == NULL)
- card->name = e_card_name_new();
- if (card->file_as == NULL)
- card->file_as = g_strdup("");
- if (card->fname == NULL)
- card->fname = g_strdup("");
- return card;
-}
-
-/**
- * e_card_new:
- * @vcard: a string in vCard format
- *
- * Returns: a new #ECard that wraps the @vcard.
- */
-ECard *
-e_card_new (const char *vcard)
-{
- return e_card_new_with_default_charset (vcard, "UTF-8");
-}
-
-ECard *
-e_card_duplicate(ECard *card)
-{
- char *vcard = e_card_get_vcard_assume_utf8(card);
- ECard *new_card = e_card_new(vcard);
- g_free (vcard);
-
- if (card->book) {
- new_card->book = card->book;
- g_object_ref (new_card->book);
- }
-
- return new_card;
-}
-
-static void
-e_card_get_today (GDate *dt)
-{
- time_t now;
- struct tm *now_tm;
- if (dt == NULL)
- return;
-
- time (&now);
- now_tm = localtime (&now);
-
- g_date_set_dmy (dt, now_tm->tm_mday, now_tm->tm_mon + 1, now_tm->tm_year + 1900);
-}
-
-float
-e_card_get_use_score(ECard *card)
-{
- GDate today, last_use;
- gint days_since_last_use;
-
- g_return_val_if_fail (card != NULL && E_IS_CARD (card), 0);
-
- if (card->last_use == NULL)
- return 0.0;
-
- e_card_get_today (&today);
- g_date_set_dmy (&last_use, card->last_use->day, card->last_use->month, card->last_use->year);
-
- days_since_last_use = g_date_get_julian (&today) - g_date_get_julian (&last_use);
-
- /* Apply a seven-day "grace period" to the use score decay. */
- days_since_last_use -= 7;
- if (days_since_last_use < 0)
- days_since_last_use = 0;
-
- return MAX (card->raw_use_score, 0) * exp (- days_since_last_use / 30.0);
-}
-
-void
-e_card_touch(ECard *card)
-{
- GDate today;
- double use_score;
-
- g_return_if_fail (card != NULL && E_IS_CARD (card));
-
- e_card_get_today (&today);
- use_score = e_card_get_use_score (card);
-
- if (card->last_use == NULL)
- card->last_use = g_new (ECardDate, 1);
-
- card->last_use->day = g_date_get_day (&today);
- card->last_use->month = g_date_get_month (&today);
- card->last_use->year = g_date_get_year (&today);
-
- card->raw_use_score = use_score + 1.0;
-}
-
-/**
- * e_card_get_id:
- * @card: an #ECard
- *
- * Returns: a string representing the id of the card, which is unique
- * within its book.
- */
-const char *
-e_card_get_id (ECard *card)
-{
- g_return_val_if_fail (card && E_IS_CARD (card), NULL);
-
- return card->id ? card->id : "";
-}
-
-/**
- * e_card_get_id:
- * @card: an #ECard
- * @id: a id in string format
- *
- * Sets the identifier of a card, which should be unique within its
- * book.
- */
-void
-e_card_set_id (ECard *card, const char *id)
-{
- g_return_if_fail (card && E_IS_CARD (card));
-
- if ( card->id )
- g_free(card->id);
- card->id = g_strdup(id ? id : "");
-}
-
-EBook *
-e_card_get_book (ECard *card)
-{
- g_return_val_if_fail (card && E_IS_CARD (card), NULL);
-
- return card->book;
-}
-
-void
-e_card_set_book (ECard *card, EBook *book)
-{
- g_return_if_fail (card && E_IS_CARD (card));
-
- if (card->book)
- g_object_unref (card->book);
- card->book = book;
- if (card->book)
- g_object_ref (card->book);
-}
-
-gchar *
-e_card_date_to_string (ECardDate *dt)
-{
- if (dt)
- return g_strdup_printf ("%04d-%02d-%02d",
- CLAMP(dt->year, 1000, 9999),
- CLAMP(dt->month, 1, 12),
- CLAMP(dt->day, 1, 31));
- else
- return NULL;
-}
-
-static VObject *
-addPropValueUTF8(VObject *o, const char *p, const char *v)
-{
- VObject *prop = addPropValue (o, p, v);
- for (; *v; v++) {
- if ((*v) & 0x80) {
- addPropValue (prop, "CHARSET", "UTF-8");
- addProp(prop, VCQuotedPrintableProp);
-
- return prop;
- }
- if (*v == '\n') {
- addProp(prop, VCQuotedPrintableProp);
- for (; *v; v++) {
- if ((*v) & 0x80) {
- addPropValue (prop, "CHARSET", "UTF-8");
- return prop;
- }
- }
- return prop;
- }
- }
- return prop;
-}
-
-static VObject *
-addPropValueQP(VObject *o, const char *p, const char *v)
-{
- VObject *prop = addPropValue (o, p, v);
- for (; *v; v++) {
- if (*v == '\n') {
- addProp(prop, VCQuotedPrintableProp);
- break;
- }
- }
- return prop;
-}
-
-static void
-addPropValueSets (VObject *o, const char *p, const char *v, gboolean assumeUTF8, gboolean *is_ascii, gboolean *has_return)
-{
- addPropValue (o, p, v);
- if (*has_return && (assumeUTF8 || !*is_ascii))
- return;
- if (*has_return) {
- for (; *v; v++) {
- if (*v & 0x80) {
- *is_ascii = FALSE;
- return;
- }
- }
- return;
- }
- if (assumeUTF8 || !*is_ascii) {
- for (; *v; v++) {
- if (*v == '\n') {
- *has_return = TRUE;
- return;
- }
- }
- return;
- }
- for (; *v; v++) {
- if (*v & 0x80) {
- *is_ascii = FALSE;
- for (; *v; v++) {
- if (*v == '\n') {
- *has_return = TRUE;
- return;
- }
- }
- return;
- }
- if (*v == '\n') {
- *has_return = TRUE;
- for (; *v; v++) {
- if (*v & 0x80) {
- *is_ascii = FALSE;
- return;
- }
- }
- return;
- }
- }
- return;
-}
-
-#define ADD_PROP_VALUE(o, p, v) (assumeUTF8 ? (addPropValueQP ((o), (p), (v))) : addPropValueUTF8 ((o), (p), (v)))
-#define ADD_PROP_VALUE_SET_IS_ASCII(o, p, v) (addPropValueSets ((o), (p), (v), assumeUTF8, &is_ascii, &has_return))
-
-
-static VObject *
-e_card_get_vobject (const ECard *card, gboolean assumeUTF8)
-{
- VObject *vobj;
-
- vobj = newVObject (VCCardProp);
-
- ADD_PROP_VALUE(vobj, VCVersionProp, "2.1");
-
- if (card->file_as && *card->file_as)
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-FILE-AS", card->file_as);
- else if (card->file_as)
- addProp(vobj, "X-EVOLUTION-FILE_AS");
-
- if (card->fname && *card->fname)
- ADD_PROP_VALUE(vobj, VCFullNameProp, card->fname);
- else if (card->fname)
- addProp(vobj, VCFullNameProp);
-
- if ( card->name && (card->name->prefix || card->name->given || card->name->additional || card->name->family || card->name->suffix) ) {
- VObject *nameprop;
- gboolean is_ascii = TRUE;
- gboolean has_return = FALSE;
- nameprop = addProp(vobj, VCNameProp);
- if ( card->name->prefix )
- ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCNamePrefixesProp, card->name->prefix);
- if ( card->name->given )
- ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCGivenNameProp, card->name->given);
- if ( card->name->additional )
- ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCAdditionalNamesProp, card->name->additional);
- if ( card->name->family )
- ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCFamilyNameProp, card->name->family);
- if ( card->name->suffix )
- ADD_PROP_VALUE_SET_IS_ASCII(nameprop, VCNameSuffixesProp, card->name->suffix);
- if (has_return)
- addProp(nameprop, VCQuotedPrintableProp);
- if (!(is_ascii || assumeUTF8))
- addPropValue (nameprop, "CHARSET", "UTF-8");
- }
- else if (card->name)
- addProp(vobj, VCNameProp);
-
-
- if ( card->address ) {
- EIterator *iterator = e_list_get_iterator(card->address);
- for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) {
- VObject *addressprop;
- ECardDeliveryAddress *address = (ECardDeliveryAddress *) e_iterator_get(iterator);
- gboolean is_ascii = TRUE;
- gboolean has_return = FALSE;
-
- addressprop = addProp(vobj, VCAdrProp);
-
- set_address_flags (addressprop, address->flags);
- if (address->po)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCPostalBoxProp, address->po);
- if (address->ext)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCExtAddressProp, address->ext);
- if (address->street)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCStreetAddressProp, address->street);
- if (address->city)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCCityProp, address->city);
- if (address->region)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCRegionProp, address->region);
- if (address->code)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCPostalCodeProp, address->code);
- if (address->country)
- ADD_PROP_VALUE_SET_IS_ASCII(addressprop, VCCountryNameProp, address->country);
-
- if (has_return)
- addProp(addressprop, VCQuotedPrintableProp);
- if (!(is_ascii || assumeUTF8))
- addPropValue (addressprop, "CHARSET", "UTF-8");
- }
- g_object_unref(iterator);
- }
-
- if ( card->address_label ) {
- EIterator *iterator = e_list_get_iterator(card->address_label);
- for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) {
- VObject *labelprop;
- ECardAddrLabel *address_label = (ECardAddrLabel *) e_iterator_get(iterator);
- if (address_label->data)
- labelprop = ADD_PROP_VALUE(vobj, VCDeliveryLabelProp, address_label->data);
- else
- labelprop = addProp(vobj, VCDeliveryLabelProp);
-
- set_address_flags (labelprop, address_label->flags);
- }
- g_object_unref(iterator);
- }
-
- if ( card->phone ) {
- EIterator *iterator = e_list_get_iterator(card->phone);
- for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) {
- VObject *phoneprop;
- ECardPhone *phone = (ECardPhone *) e_iterator_get(iterator);
- phoneprop = ADD_PROP_VALUE(vobj, VCTelephoneProp, phone->number);
-
- set_phone_flags (phoneprop, phone->flags);
- }
- g_object_unref(iterator);
- }
-
- if ( card->email ) {
- EIterator *iterator = e_list_get_iterator(card->email);
- for ( ; e_iterator_is_valid(iterator) ;e_iterator_next(iterator) ) {
- VObject *emailprop;
- emailprop = ADD_PROP_VALUE(vobj, VCEmailAddressProp, (char *) e_iterator_get(iterator));
- addProp (emailprop, VCInternetProp);
- }
- g_object_unref(iterator);
- }
-
- if ( card->bday ) {
- char *value;
- value = e_card_date_to_string (card->bday);
- ADD_PROP_VALUE(vobj, VCBirthDateProp, value);
- g_free(value);
- }
-
- if (card->url)
- ADD_PROP_VALUE(vobj, VCURLProp, card->url);
-
- if (card->org || card->org_unit) {
- VObject *orgprop;
- gboolean is_ascii = TRUE;
- gboolean has_return = FALSE;
- orgprop = addProp(vobj, VCOrgProp);
-
- if (card->org)
- ADD_PROP_VALUE_SET_IS_ASCII(orgprop, VCOrgNameProp, card->org);
- if (card->org_unit)
- ADD_PROP_VALUE_SET_IS_ASCII(orgprop, VCOrgUnitProp, card->org_unit);
-
- if (has_return)
- addProp(orgprop, VCQuotedPrintableProp);
- if (!(is_ascii || assumeUTF8))
- addPropValue (orgprop, "CHARSET", "UTF-8");
- }
-
- if (card->office)
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-OFFICE", card->office);
-
- if (card->title)
- ADD_PROP_VALUE(vobj, VCTitleProp, card->title);
-
- if (card->role)
- ADD_PROP_VALUE(vobj, VCBusinessRoleProp, card->role);
-
- if (card->manager)
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-MANAGER", card->manager);
-
- if (card->assistant)
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-ASSISTANT", card->assistant);
-
- if (card->nickname)
- ADD_PROP_VALUE(vobj, "NICKNAME", card->nickname);
-
- if (card->spouse)
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-SPOUSE", card->spouse);
-
- if ( card->anniversary ) {
- char *value;
- value = e_card_date_to_string (card->anniversary);
- ADD_PROP_VALUE(vobj, "X-EVOLUTION-ANNIVERSARY", value);
- g_free(value);
- }
-
- if (card->mailer) {
- ADD_PROP_VALUE(vobj, VCMailerProp, card->mailer);
- }
-
- if (card->caluri)
- addPropValueQP(vobj, "CALURI", card->caluri);
-
- if (card->fburl)
- ADD_PROP_VALUE(vobj, "FBURL", card->fburl);
-
- if (card->icscalendar)
- ADD_PROP_VALUE(vobj, "ICSCALENDAR", card->icscalendar);
-
- if (card->note) {
- VObject *noteprop;
-
- noteprop = ADD_PROP_VALUE(vobj, VCNoteProp, card->note);
- }
-
- if (card->last_use) {
- char *value;
- value = e_card_date_to_string (card->last_use);
- ADD_PROP_VALUE (vobj, "X-EVOLUTION-LAST-USE", value);
- g_free (value);
- }
-
- if (card->raw_use_score > 0) {
- char *value;
- value = g_strdup_printf ("%f", card->raw_use_score);
- ADD_PROP_VALUE (vobj, "X-EVOLUTION-USE-SCORE", value);
- g_free (value);
- }
-
- if (card->related_contacts && *card->related_contacts) {
- ADD_PROP_VALUE(vobj, XEV_RELATED_CONTACTS, card->related_contacts);
- }
-
- if (card->categories) {
- EIterator *iterator;
- int length = 0;
- char *string;
- char *stringptr;
- for (iterator = e_list_get_iterator(card->categories); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- length += strlen(e_iterator_get(iterator)) + 1;
- }
- string = g_new(char, length + 1);
- stringptr = string;
- *stringptr = 0;
- for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- strcpy(stringptr, e_iterator_get(iterator));
- stringptr += strlen(stringptr);
- *stringptr = ',';
- stringptr++;
- *stringptr = 0;
- }
- if (stringptr > string) {
- stringptr --;
- *stringptr = 0;
- }
- ADD_PROP_VALUE (vobj, "CATEGORIES", string);
- g_free(string);
- }
-
- if (card->wants_html_set) {
- ADD_PROP_VALUE (vobj, XEV_WANTS_HTML, card->wants_html ? "TRUE" : "FALSE");
- }
-
- if (card->list) {
- ADD_PROP_VALUE (vobj, XEV_LIST, "TRUE");
- ADD_PROP_VALUE (vobj, XEV_LIST_SHOW_ADDRESSES, card->list_show_addresses ? "TRUE" : "FALSE");
- }
-
- if (card->arbitrary) {
- EIterator *iterator;
- for (iterator = e_list_get_iterator(card->arbitrary); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get(iterator);
- VObject *arb_object;
- if (arbitrary->value) {
- arb_object = ADD_PROP_VALUE (vobj, XEV_ARBITRARY, arbitrary->value);
- } else {
- arb_object = addProp (vobj, XEV_ARBITRARY);
- }
- if (arbitrary->type) {
- ADD_PROP_VALUE (arb_object, "TYPE", arbitrary->type);
- }
- if (arbitrary->key) {
- addProp (arb_object, arbitrary->key);
- }
- }
- }
-
- addPropValueQP (vobj, VCUniqueStringProp, (card->id ? card->id : ""));
-
- return vobj;
-}
-
-/**
- * e_card_get_vcard:
- * @card: an #ECard
- *
- * Returns: a string in vCard format, which is wrapped by the @card.
- */
-char *
-e_card_get_vcard (ECard *card)
-{
- VObject *vobj;
- char *temp, *ret_val;
-
- vobj = e_card_get_vobject (card, FALSE);
- temp = writeMemVObject(NULL, NULL, vobj);
- ret_val = g_strdup(temp);
- free(temp);
- cleanVObject(vobj);
- return ret_val;
-}
-
-char *
-e_card_get_vcard_assume_utf8 (ECard *card)
-{
- VObject *vobj;
- char *temp, *ret_val;
-
- vobj = e_card_get_vobject (card, TRUE);
- temp = writeMemVObject(NULL, NULL, vobj);
- ret_val = g_strdup(temp);
- free(temp);
- cleanVObject(vobj);
- return ret_val;
-}
-
-/**
- * e_card_list_get_vcard:
- * @list: a list of #ECards
- *
- * Returns: a string in vCard format.
- */
-char *
-e_card_list_get_vcard (const GList *list)
-{
- VObject *vobj;
-
- char *temp, *ret_val;
-
- vobj = NULL;
-
- for (; list; list = list->next) {
- VObject *tempvobj;
- ECard *card = list->data;
-
- tempvobj = e_card_get_vobject (card, FALSE);
- addList (&vobj, tempvobj);
- }
- temp = writeMemVObjects(NULL, NULL, vobj);
- ret_val = g_strdup(temp);
- free(temp);
- cleanVObjects(vobj);
- return ret_val;
-}
-
-static void
-parse_file_as(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->file_as )
- g_free(card->file_as);
- assign_string(vobj, default_charset, &(card->file_as));
-}
-
-static void
-parse_name(ECard *card, VObject *vobj, const char *default_charset)
-{
- e_card_name_unref(card->name);
-
- card->name = e_card_name_new();
-
- card->name->family = e_v_object_get_child_value (vobj, VCFamilyNameProp, default_charset);
- card->name->given = e_v_object_get_child_value (vobj, VCGivenNameProp, default_charset);
- card->name->additional = e_v_object_get_child_value (vobj, VCAdditionalNamesProp, default_charset);
- card->name->prefix = e_v_object_get_child_value (vobj, VCNamePrefixesProp, default_charset);
- card->name->suffix = e_v_object_get_child_value (vobj, VCNameSuffixesProp, default_charset);
-}
-
-static void
-parse_full_name(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->fname )
- g_free(card->fname);
- assign_string(vobj, default_charset, &(card->fname));
-}
-
-static void
-parse_email(ECard *card, VObject *vobj, const char *default_charset)
-{
- char *next_email;
- EList *list;
-
- assign_string(vobj, default_charset, &next_email);
- g_object_get(card,
- "email", &list,
- NULL);
- e_list_append(list, next_email);
- g_free (next_email);
- g_object_unref(list);
-}
-
-/* Deal with charset */
-static void
-parse_bday(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if ( card->bday )
- g_free(card->bday);
- card->bday = g_new(ECardDate, 1);
- *(card->bday) = e_card_date_from_string(str);
- free(str);
- }
-}
-
-static void
-parse_phone(ECard *card, VObject *vobj, const char *default_charset)
-{
- ECardPhone *next_phone = e_card_phone_new ();
- EList *list;
-
- assign_string(vobj, default_charset, &(next_phone->number));
- next_phone->flags = get_phone_flags(vobj);
-
- g_object_get(card,
- "phone", &list,
- NULL);
- e_list_append(list, next_phone);
- e_card_phone_unref (next_phone);
- g_object_unref(list);
-}
-
-static void
-parse_address(ECard *card, VObject *vobj, const char *default_charset)
-{
- ECardDeliveryAddress *next_addr = e_card_delivery_address_new ();
- EList *list;
-
- next_addr->flags = get_address_flags (vobj);
- next_addr->po = e_v_object_get_child_value (vobj, VCPostalBoxProp, default_charset);
- next_addr->ext = e_v_object_get_child_value (vobj, VCExtAddressProp, default_charset);
- next_addr->street = e_v_object_get_child_value (vobj, VCStreetAddressProp, default_charset);
- next_addr->city = e_v_object_get_child_value (vobj, VCCityProp, default_charset);
- next_addr->region = e_v_object_get_child_value (vobj, VCRegionProp, default_charset);
- next_addr->code = e_v_object_get_child_value (vobj, VCPostalCodeProp, default_charset);
- next_addr->country = e_v_object_get_child_value (vobj, VCCountryNameProp, default_charset);
-
- g_object_get(card,
- "address", &list,
- NULL);
- e_list_append(list, next_addr);
- e_card_delivery_address_unref (next_addr);
- g_object_unref(list);
-}
-
-static void
-parse_address_label(ECard *card, VObject *vobj, const char *default_charset)
-{
- ECardAddrLabel *next_addr = e_card_address_label_new ();
- EList *list;
-
- next_addr->flags = get_address_flags (vobj);
- assign_string(vobj, default_charset, &next_addr->data);
-
- g_object_get(card,
- "address_label", &list,
- NULL);
- e_list_append(list, next_addr);
- e_card_address_label_unref (next_addr);
- g_object_unref(list);
-}
-
-static void
-parse_url(ECard *card, VObject *vobj, const char *default_charset)
-{
- if (card->url)
- g_free(card->url);
- assign_string(vobj, default_charset, &(card->url));
-}
-
-static void
-parse_org(ECard *card, VObject *vobj, const char *default_charset)
-{
- char *temp;
-
- temp = e_v_object_get_child_value(vobj, VCOrgNameProp, default_charset);
- g_free(card->org);
- card->org = temp;
-
- temp = e_v_object_get_child_value(vobj, VCOrgUnitProp, default_charset);
- g_free(card->org_unit);
- card->org_unit = temp;
-}
-
-static void
-parse_office(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->office )
- g_free(card->office);
- assign_string(vobj, default_charset, &(card->office));
-}
-
-static void
-parse_title(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->title )
- g_free(card->title);
- assign_string(vobj, default_charset, &(card->title));
-}
-
-static void
-parse_role(ECard *card, VObject *vobj, const char *default_charset)
-{
- if (card->role)
- g_free(card->role);
- assign_string(vobj, default_charset, &(card->role));
-}
-
-static void
-parse_manager(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->manager )
- g_free(card->manager);
- assign_string(vobj, default_charset, &(card->manager));
-}
-
-static void
-parse_assistant(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->assistant )
- g_free(card->assistant);
- assign_string(vobj, default_charset, &(card->assistant));
-}
-
-static void
-parse_nickname(ECard *card, VObject *vobj, const char *default_charset)
-{
- if (card->nickname)
- g_free(card->nickname);
- assign_string(vobj, default_charset, &(card->nickname));
-}
-
-static void
-parse_spouse(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->spouse )
- g_free(card->spouse);
- assign_string(vobj, default_charset, &(card->spouse));
-}
-
-/* Deal with charset */
-static void
-parse_anniversary(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if (card->anniversary)
- g_free(card->anniversary);
- card->anniversary = g_new(ECardDate, 1);
- *(card->anniversary) = e_card_date_from_string(str);
- free(str);
- }
-}
-
-static void
-parse_mailer(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( card->mailer )
- g_free(card->mailer);
- assign_string(vobj, default_charset, &(card->mailer));
-}
-
-static void
-parse_caluri(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->caluri);
- assign_string(vobj, default_charset, &(card->caluri));
-}
-
-static void
-parse_fburl(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->fburl);
- assign_string(vobj, default_charset, &(card->fburl));
-}
-
-static void
-parse_icscalendar(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->icscalendar);
- assign_string(vobj, default_charset, &(card->icscalendar));
-}
-
-static void
-parse_note(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->note);
- assign_string(vobj, default_charset, &(card->note));
-}
-
-static void
-parse_related_contacts(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->related_contacts);
- assign_string(vobj, default_charset, &(card->related_contacts));
-}
-
-static void
-add_list_unique(ECard *card, EList *list, char *string)
-{
- char *temp = e_strdup_strip(string);
- EIterator *iterator;
-
- if (!*temp) {
- g_free(temp);
- return;
- }
- for ( iterator = e_list_get_iterator(list); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- if (!strcmp(e_iterator_get(iterator), temp)) {
- break;
- }
- }
- if (!e_iterator_is_valid(iterator)) {
- e_list_append(list, temp);
- }
- g_free(temp);
- g_object_unref(iterator);
-}
-
-static void
-do_parse_categories(ECard *card, char *str)
-{
- int length = strlen(str);
- char *copy = g_new(char, length + 1);
- int i, j;
- EList *list;
- g_object_get(card,
- "category_list", &list,
- NULL);
- for (i = 0, j = 0; str[i]; i++, j++) {
- switch (str[i]) {
- case '\\':
- i++;
- if (str[i]) {
- copy[j] = str[i];
- } else
- i--;
- break;
- case ',':
- copy[j] = 0;
- add_list_unique(card, list, copy);
- j = -1;
- break;
- default:
- copy[j] = str[i];
- break;
- }
- }
- copy[j] = 0;
- add_list_unique(card, list, copy);
- g_object_unref(list);
- g_free(copy);
-}
-
-/* Deal with charset */
-static void
-parse_categories(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- do_parse_categories(card, str);
- free(str);
- }
-}
-
-/* Deal with charset */
-static void
-parse_wants_html(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if (!strcasecmp(str, "true")) {
- card->wants_html = TRUE;
- card->wants_html_set = TRUE;
- }
- if (!strcasecmp(str, "false")) {
- card->wants_html = FALSE;
- card->wants_html_set = TRUE;
- }
- free(str);
- }
-}
-
-/* Deal with charset */
-static void
-parse_list(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if (!strcasecmp(str, "true")) {
- card->list = TRUE;
- }
- if (!strcasecmp(str, "false")) {
- card->list = FALSE;
- }
- free(str);
- }
-}
-
-/* Deal with charset */
-static void
-parse_list_show_addresses(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if (!strcasecmp(str, "true")) {
- card->list_show_addresses = TRUE;
- }
- if (!strcasecmp(str, "false")) {
- card->list_show_addresses = FALSE;
- }
- free(str);
- }
-}
-
-typedef union ValueItem {
- const char *strs;
- const wchar_t *ustrs;
- unsigned int i;
- unsigned long l;
- void *any;
- VObject *vobj;
-} ValueItem;
-
-struct VObject {
- VObject *next;
- const char *id;
- VObject *prop;
- unsigned short valType;
- ValueItem val;
-};
-
-static void
-parse_arbitrary(ECard *card, VObject *vobj, const char *default_charset)
-{
- ECardArbitrary *arbitrary = e_card_arbitrary_new();
- VObjectIterator iterator;
- EList *list;
- for ( initPropIterator (&iterator, vobj); moreIteration(&iterator); ) {
- VObject *temp = nextVObject(&iterator);
- const char *name = vObjectName(temp);
- if (name && !strcmp(name, "TYPE")) {
- g_free(arbitrary->type);
- assign_string(temp, default_charset, &(arbitrary->type));
- } else {
- g_free(arbitrary->key);
- arbitrary->key = g_strdup(name);
- }
- }
-
- assign_string(vobj, default_charset, &(arbitrary->value));
-
- g_object_get(card,
- "arbitrary", &list,
- NULL);
- e_list_append(list, arbitrary);
- e_card_arbitrary_unref(arbitrary);
- g_object_unref(list);
-}
-
-static void
-parse_id(ECard *card, VObject *vobj, const char *default_charset)
-{
- g_free(card->id);
- assign_string(vobj, default_charset, &(card->id));
-}
-
-/* Deal with charset */
-static void
-parse_last_use(ECard *card, VObject *vobj, const char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- g_free(card->last_use);
- card->last_use = g_new(ECardDate, 1);
- *(card->last_use) = e_card_date_from_string(str);
- free(str);
- }
-}
-
-/* Deal with charset */
-static void
-parse_use_score(ECard *card, VObject *vobj, const char *default_charset)
-{
- card->raw_use_score = 0;
-
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- card->raw_use_score = MAX(0, atof (str));
- free (str);
- }
-}
-
-static void
-parse_attribute(ECard *card, VObject *vobj, const char *default_charset)
-{
- ParsePropertyFunc function = g_hash_table_lookup(E_CARD_GET_CLASS(card)->attribute_jump_table, vObjectName(vobj));
- if ( function )
- function(card, vobj, default_charset);
-}
-
-static void
-parse(ECard *card, VObject *vobj, const char *default_charset)
-{
- VObjectIterator iterator;
- initPropIterator(&iterator, vobj);
- while(moreIteration (&iterator)) {
- parse_attribute(card, nextVObject(&iterator), default_charset);
- }
- if (!card->fname) {
- card->fname = g_strdup("");
- }
- if (!card->name) {
- card->name = e_card_name_from_string(card->fname);
- }
- if (!card->file_as) {
- ECardName *name = card->name;
- char *strings[3], **stringptr;
- char *string;
- stringptr = strings;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- *stringptr = NULL;
- string = g_strjoinv(", ", strings);
- card->file_as = string;
- }
-}
-
-static void
-e_card_class_init (ECardClass *klass)
-{
- int i;
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS(klass);
-
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- klass->attribute_jump_table = g_hash_table_new(g_str_hash, g_str_equal);
-
- for ( i = 0; i < sizeof(attribute_jump_array) / sizeof(attribute_jump_array[0]); i++ ) {
- g_hash_table_insert(klass->attribute_jump_table, attribute_jump_array[i].key, attribute_jump_array[i].function);
- }
-
- object_class->dispose = e_card_dispose;
- object_class->get_property = e_card_get_property;
- object_class->set_property = e_card_set_property;
-
- g_object_class_install_property (object_class, PROP_FILE_AS,
- g_param_spec_string ("file_as",
- _("File As"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_FULL_NAME,
- g_param_spec_string ("full_name",
- _("Full Name"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_NAME,
- g_param_spec_pointer ("name",
- _("Name"),
- /*_( */"XXX blurb" /*)*/,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ADDRESS,
- g_param_spec_object ("address",
- _("Address"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_ADDRESS_LABEL,
- g_param_spec_object ("address_label",
- _("Address Label"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_PHONE,
- g_param_spec_object ("phone",
- _("Phone"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_EMAIL,
- g_param_spec_object ("email",
- _("Email"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_BIRTH_DATE,
- g_param_spec_pointer ("birth_date",
- _("Birth date"),
- /*_( */"XXX blurb" /*)*/,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_URL,
- g_param_spec_string ("url",
- _("URL"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ORG,
- g_param_spec_string ("org",
- _("Organization"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ORG_UNIT,
- g_param_spec_string ("org_unit",
- _("Organizational Unit"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_OFFICE,
- g_param_spec_string ("office",
- _("Office"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_TITLE,
- g_param_spec_string ("title",
- _("Title"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ROLE,
- g_param_spec_string ("role",
- _("Role"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_MANAGER,
- g_param_spec_string ("manager",
- _("Manager"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ASSISTANT,
- g_param_spec_string ("assistant",
- _("Assistant"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_NICKNAME,
- g_param_spec_string ("nickname",
- _("Nickname"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_SPOUSE,
- g_param_spec_string ("spouse",
- _("Spouse"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ANNIVERSARY,
- g_param_spec_pointer ("anniversary",
- _("Anniversary"),
- /*_( */"XXX blurb" /*)*/,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_MAILER,
- g_param_spec_string ("mailer",
- _("Mailer"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_CALURI,
- g_param_spec_string ("caluri",
- _("Calendar URI"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_FBURL,
- g_param_spec_string ("fburl",
- _("Free/Busy URL"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ICSCALENDAR,
- g_param_spec_string ("icscalendar",
- _("ICS Calendar"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_NOTE,
- g_param_spec_string ("note",
- _("Note"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_RELATED_CONTACTS,
- g_param_spec_string ("related_contacts",
- _("Related Contacts"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_CATEGORIES,
- g_param_spec_string ("categories",
- _("Categories"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_CATEGORY_LIST,
- g_param_spec_object ("category list",
- _("Category List"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_WANTS_HTML,
- g_param_spec_boolean ("wants_html",
- _("Wants HTML"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_WANTS_HTML_SET,
- g_param_spec_boolean ("wants_html_set",
- _("Wants HTML set"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_EVOLUTION_LIST,
- g_param_spec_boolean ("list",
- _("List"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_EVOLUTION_LIST_SHOW_ADDRESSES,
- g_param_spec_boolean ("list_show_addresses",
- _("List Show Addresses"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ARBITRARY,
- g_param_spec_object ("arbitrary",
- _("Arbitrary"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_LIST,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_ID,
- g_param_spec_string ("id",
- _("ID"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_LAST_USE,
- g_param_spec_pointer ("last_use",
- _("Last Use"),
- /*_( */"XXX blurb" /*)*/,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_USE_SCORE,
- /* XXX at some point we
- should remove
- LAX_VALIDATION and figure
- out some hard min & max
- scores. */
- g_param_spec_float ("use_score",
- _("Use Score"),
- /*_( */"XXX blurb" /*)*/,
- 0.0,
- 0.0,
- 0.0,
- G_PARAM_READWRITE | G_PARAM_LAX_VALIDATION));
-}
-
-ECardPhone *
-e_card_phone_new (void)
-{
- ECardPhone *newphone = g_new(ECardPhone, 1);
-
- newphone->ref_count = 1;
- newphone->number = NULL;
- newphone->flags = 0;
-
- return newphone;
-}
-
-void
-e_card_phone_unref (ECardPhone *phone)
-{
- if (phone) {
- phone->ref_count --;
- if (phone->ref_count == 0) {
- g_free(phone->number);
- g_free(phone);
- }
- }
-}
-
-ECardPhone *
-e_card_phone_ref (const ECardPhone *phone)
-{
- ECardPhone *phone_mutable = (ECardPhone *) phone;
- if (phone_mutable)
- phone_mutable->ref_count ++;
- return phone_mutable;
-}
-
-ECardPhone *
-e_card_phone_copy (const ECardPhone *phone)
-{
- if ( phone ) {
- ECardPhone *phone_copy = e_card_phone_new();
- phone_copy->number = g_strdup(phone->number);
- phone_copy->flags = phone->flags;
- return phone_copy;
- } else
- return NULL;
-}
-
-ECardDeliveryAddress *
-e_card_delivery_address_new (void)
-{
- ECardDeliveryAddress *newaddr = g_new(ECardDeliveryAddress, 1);
-
- newaddr->ref_count = 1;
- newaddr->po = NULL;
- newaddr->ext = NULL;
- newaddr->street = NULL;
- newaddr->city = NULL;
- newaddr->region = NULL;
- newaddr->code = NULL;
- newaddr->country = NULL;
- newaddr->flags = 0;
-
- return newaddr;
-}
-
-void
-e_card_delivery_address_unref (ECardDeliveryAddress *addr)
-{
- if ( addr ) {
- addr->ref_count --;
- if (addr->ref_count == 0) {
- g_free(addr->po);
- g_free(addr->ext);
- g_free(addr->street);
- g_free(addr->city);
- g_free(addr->region);
- g_free(addr->code);
- g_free(addr->country);
- g_free(addr);
- }
- }
-}
-
-ECardDeliveryAddress *
-e_card_delivery_address_ref (const ECardDeliveryAddress *addr)
-{
- ECardDeliveryAddress *addr_mutable = (ECardDeliveryAddress *) addr;
- if (addr_mutable)
- addr_mutable->ref_count ++;
- return addr_mutable;
-}
-
-ECardDeliveryAddress *
-e_card_delivery_address_copy (const ECardDeliveryAddress *addr)
-{
- if ( addr ) {
- ECardDeliveryAddress *addr_copy = e_card_delivery_address_new ();
- addr_copy->po = g_strdup(addr->po );
- addr_copy->ext = g_strdup(addr->ext );
- addr_copy->street = g_strdup(addr->street );
- addr_copy->city = g_strdup(addr->city );
- addr_copy->region = g_strdup(addr->region );
- addr_copy->code = g_strdup(addr->code );
- addr_copy->country = g_strdup(addr->country);
- addr_copy->flags = addr->flags;
- return addr_copy;
- } else
- return NULL;
-}
-
-gboolean
-e_card_delivery_address_is_empty (const ECardDeliveryAddress *addr)
-{
- return (((addr->po == NULL) || (*addr->po == 0)) &&
- ((addr->ext == NULL) || (*addr->ext == 0)) &&
- ((addr->street == NULL) || (*addr->street == 0)) &&
- ((addr->city == NULL) || (*addr->city == 0)) &&
- ((addr->region == NULL) || (*addr->region == 0)) &&
- ((addr->code == NULL) || (*addr->code == 0)) &&
- ((addr->country == NULL) || (*addr->country == 0)));
-}
-
-ECardDeliveryAddress *
-e_card_delivery_address_from_label(const ECardAddrLabel *label)
-{
- ECardDeliveryAddress *addr = e_card_delivery_address_new ();
- EAddressWestern *western = e_address_western_parse (label->data);
-
- addr->po = g_strdup (western->po_box );
- addr->ext = g_strdup (western->extended );
- addr->street = g_strdup (western->street );
- addr->city = g_strdup (western->locality );
- addr->region = g_strdup (western->region );
- addr->code = g_strdup (western->postal_code);
- addr->country = g_strdup (western->country );
- addr->flags = label->flags;
-
- e_address_western_free(western);
-
- return addr;
-}
-
-char *
-e_card_delivery_address_to_string(const ECardDeliveryAddress *addr)
-{
- char *strings[5], **stringptr = strings;
- char *line1, *line22, *line2;
- char *final;
- if (addr->po && *addr->po)
- *(stringptr++) = addr->po;
- if (addr->street && *addr->street)
- *(stringptr++) = addr->street;
- *stringptr = NULL;
- line1 = g_strjoinv(" ", strings);
- stringptr = strings;
- if (addr->region && *addr->region)
- *(stringptr++) = addr->region;
- if (addr->code && *addr->code)
- *(stringptr++) = addr->code;
- *stringptr = NULL;
- line22 = g_strjoinv(" ", strings);
- stringptr = strings;
- if (addr->city && *addr->city)
- *(stringptr++) = addr->city;
- if (line22 && *line22)
- *(stringptr++) = line22;
- *stringptr = NULL;
- line2 = g_strjoinv(", ", strings);
- stringptr = strings;
- if (line1 && *line1)
- *(stringptr++) = line1;
- if (addr->ext && *addr->ext)
- *(stringptr++) = addr->ext;
- if (line2 && *line2)
- *(stringptr++) = line2;
- if (addr->country && *addr->country)
- *(stringptr++) = addr->country;
- *stringptr = NULL;
- final = g_strjoinv("\n", strings);
- g_free(line1);
- g_free(line22);
- g_free(line2);
- return final;
-}
-
-ECardAddrLabel *
-e_card_delivery_address_to_label (const ECardDeliveryAddress *addr)
-{
- ECardAddrLabel *label;
- label = e_card_address_label_new();
- label->flags = addr->flags;
- label->data = e_card_delivery_address_to_string(addr);
-
- return label;
-}
-
-ECardAddrLabel *
-e_card_address_label_new (void)
-{
- ECardAddrLabel *newaddr = g_new(ECardAddrLabel, 1);
-
- newaddr->ref_count = 1;
- newaddr->data = NULL;
- newaddr->flags = 0;
-
- return newaddr;
-}
-
-void
-e_card_address_label_unref (ECardAddrLabel *addr)
-{
- if (addr) {
- addr->ref_count --;
- if (addr->ref_count == 0) {
- g_free(addr->data);
- g_free(addr);
- }
- }
-}
-
-ECardAddrLabel *
-e_card_address_label_ref (const ECardAddrLabel *addr)
-{
- ECardAddrLabel *addr_mutable = (ECardAddrLabel *) addr;
- if (addr_mutable)
- addr_mutable->ref_count ++;
- return addr_mutable;
-}
-
-ECardAddrLabel *
-e_card_address_label_copy (const ECardAddrLabel *addr)
-{
- if ( addr ) {
- ECardAddrLabel *addr_copy = e_card_address_label_new ();
- addr_copy->data = g_strdup(addr->data);
- addr_copy->flags = addr->flags;
- return addr_copy;
- } else
- return NULL;
-}
-
-ECardName *e_card_name_new(void)
-{
- ECardName *newname = g_new(ECardName, 1);
-
- newname->ref_count = 1;
- newname->prefix = NULL;
- newname->given = NULL;
- newname->additional = NULL;
- newname->family = NULL;
- newname->suffix = NULL;
-
- return newname;
-}
-
-void
-e_card_name_unref(ECardName *name)
-{
- if (name) {
- name->ref_count --;
- if (name->ref_count == 0) {
- g_free (name->prefix);
- g_free (name->given);
- g_free (name->additional);
- g_free (name->family);
- g_free (name->suffix);
- g_free (name);
- }
- }
-}
-
-ECardName *
-e_card_name_ref(const ECardName *name)
-{
- ECardName *name_mutable = (ECardName *) name;
- if (name_mutable)
- name_mutable->ref_count ++;
- return name_mutable;
-}
-
-ECardName *
-e_card_name_copy(const ECardName *name)
-{
- if (name) {
- ECardName *newname = e_card_name_new ();
-
- newname->prefix = g_strdup(name->prefix);
- newname->given = g_strdup(name->given);
- newname->additional = g_strdup(name->additional);
- newname->family = g_strdup(name->family);
- newname->suffix = g_strdup(name->suffix);
-
- return newname;
- } else
- return NULL;
-}
-
-
-char *
-e_card_name_to_string(const ECardName *name)
-{
- char *strings[6], **stringptr = strings;
-
- g_return_val_if_fail (name != NULL, NULL);
-
- if (name->prefix && *name->prefix)
- *(stringptr++) = name->prefix;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- if (name->additional && *name->additional)
- *(stringptr++) = name->additional;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- if (name->suffix && *name->suffix)
- *(stringptr++) = name->suffix;
- *stringptr = NULL;
- return g_strjoinv(" ", strings);
-}
-
-ECardName *
-e_card_name_from_string(const char *full_name)
-{
- ECardName *name = e_card_name_new ();
- ENameWestern *western = e_name_western_parse (full_name);
-
- name->prefix = g_strdup (western->prefix);
- name->given = g_strdup (western->first );
- name->additional = g_strdup (western->middle);
- name->family = g_strdup (western->last );
- name->suffix = g_strdup (western->suffix);
-
- e_name_western_free(western);
-
- return name;
-}
-
-ECardArbitrary *
-e_card_arbitrary_new(void)
-{
- ECardArbitrary *arbitrary = g_new(ECardArbitrary, 1);
- arbitrary->ref_count = 1;
- arbitrary->key = NULL;
- arbitrary->type = NULL;
- arbitrary->value = NULL;
- return arbitrary;
-}
-
-void
-e_card_arbitrary_unref(ECardArbitrary *arbitrary)
-{
- if (arbitrary) {
- arbitrary->ref_count --;
- if (arbitrary->ref_count == 0) {
- g_free(arbitrary->key);
- g_free(arbitrary->type);
- g_free(arbitrary->value);
- g_free(arbitrary);
- }
- }
-}
-
-ECardArbitrary *
-e_card_arbitrary_copy(const ECardArbitrary *arbitrary)
-{
- if (arbitrary) {
- ECardArbitrary *arb_copy = e_card_arbitrary_new ();
- arb_copy->key = g_strdup(arbitrary->key);
- arb_copy->type = g_strdup(arbitrary->type);
- arb_copy->value = g_strdup(arbitrary->value);
- return arb_copy;
- } else
- return NULL;
-}
-
-ECardArbitrary *
-e_card_arbitrary_ref(const ECardArbitrary *arbitrary)
-{
- ECardArbitrary *arbitrary_mutable = (ECardArbitrary *) arbitrary;
- if (arbitrary_mutable)
- arbitrary_mutable->ref_count ++;
- return arbitrary_mutable;
-}
-
-/* EMail matching */
-static gboolean
-e_card_email_match_single_string (const gchar *a, const gchar *b)
-{
- const gchar *xa = NULL, *xb = NULL;
- gboolean match = TRUE;
-
- for (xa=a; *xa && *xa != '@'; ++xa);
- for (xb=b; *xb && *xb != '@'; ++xb);
-
- if (xa-a != xb-b || *xa != *xb || g_ascii_strncasecmp (a, b, xa-a))
- return FALSE;
-
- if (*xa == '\0')
- return TRUE;
-
- /* Find the end of the string, then walk through backwards comparing.
- This is so that we'll match joe@foobar.com and joe@mail.foobar.com.
- */
- while (*xa)
- ++xa;
- while (*xb)
- ++xb;
-
- while (match && *xa != '@' && *xb != '@') {
- match = (tolower (*xa) == tolower (*xb));
- --xa;
- --xb;
- }
-
- match = match && ((tolower (*xa) == tolower (*xb)) || (*xa == '.') || (*xb == '.'));
-
- return match;
-}
-
-gboolean
-e_card_email_match_string (const ECard *card, const gchar *str)
-{
- EIterator *iter;
-
- g_return_val_if_fail (card && E_IS_CARD (card), FALSE);
- g_return_val_if_fail (str != NULL, FALSE);
-
- if (!card->email)
- return FALSE;
-
- iter = e_list_get_iterator (card->email);
- for (e_iterator_reset (iter); e_iterator_is_valid (iter); e_iterator_next (iter)) {
- if (e_card_email_match_single_string (e_iterator_get (iter), str))
- return TRUE;
- }
- g_object_unref (iter);
-
- return FALSE;
-}
-
-gint
-e_card_email_find_number (const ECard *card, const gchar *email)
-{
- EIterator *iter;
- gint count = 0;
-
- g_return_val_if_fail (E_IS_CARD (card), -1);
- g_return_val_if_fail (email != NULL, -1);
-
- if (!card->email)
- return -1;
-
- iter = e_list_get_iterator (card->email);
- for (e_iterator_reset (iter); e_iterator_is_valid (iter); e_iterator_next (iter)) {
- if (!g_ascii_strcasecmp (e_iterator_get (iter), email))
- goto finished;
- ++count;
- }
- count = -1;
-
- finished:
- g_object_unref (iter);
-
- return count;
-}
-
-/*
- * ECard lifecycle management and vCard loading/saving.
- */
-
-static void
-e_card_dispose (GObject *object)
-{
- ECard *card = E_CARD(object);
-
-#define FREE_IF(x) do { if ((x)) { g_free (x); x = NULL; } } while (0)
-#define UNREF_IF(x) do { if ((x)) { g_object_unref (x); x = NULL; } } while (0)
-
- FREE_IF (card->id);
- UNREF_IF (card->book);
- FREE_IF(card->file_as);
- FREE_IF(card->fname);
- if (card->name) {
- e_card_name_unref(card->name);
- card->name = NULL;
- }
- FREE_IF(card->bday);
-
- FREE_IF(card->url);
- FREE_IF(card->org);
- FREE_IF(card->org_unit);
- FREE_IF(card->office);
- FREE_IF(card->title);
- FREE_IF(card->role);
- FREE_IF(card->manager);
- FREE_IF(card->assistant);
- FREE_IF(card->nickname);
- FREE_IF(card->spouse);
- FREE_IF(card->anniversary);
- FREE_IF(card->caluri);
- FREE_IF(card->fburl);
- FREE_IF(card->icscalendar);
- FREE_IF(card->last_use);
- FREE_IF(card->note);
- FREE_IF(card->related_contacts);
-
- UNREF_IF (card->categories);
- UNREF_IF (card->email);
- UNREF_IF (card->phone);
- UNREF_IF (card->address);
- UNREF_IF (card->address_label);
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-
-/* Set_arg handler for the card */
-static void
-e_card_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- ECard *card;
-
- card = E_CARD (object);
-
- switch (prop_id) {
- case PROP_FILE_AS:
- g_free(card->file_as);
- card->file_as = g_strdup(g_value_get_string (value));
- if (card->file_as == NULL)
- card->file_as = g_strdup("");
- break;
-
- case PROP_FULL_NAME:
- g_free(card->fname);
- card->fname = g_strdup(g_value_get_string (value));
- if (card->fname == NULL)
- card->fname = g_strdup("");
-
- e_card_name_unref (card->name);
- card->name = e_card_name_from_string (card->fname);
- break;
- case PROP_NAME:
- e_card_name_unref (card->name);
- card->name = e_card_name_ref(g_value_get_pointer (value));
- if (card->name == NULL)
- card->name = e_card_name_new();
- if (card->fname == NULL) {
- card->fname = e_card_name_to_string(card->name);
- }
- if (card->file_as == NULL) {
- ECardName *name = card->name;
- char *strings[3], **stringptr;
- char *string;
- stringptr = strings;
- if (name->family && *name->family)
- *(stringptr++) = name->family;
- if (name->given && *name->given)
- *(stringptr++) = name->given;
- *stringptr = NULL;
- string = g_strjoinv(", ", strings);
- card->file_as = string;
- }
- break;
- case PROP_CATEGORIES:
- if (card->categories)
- g_object_unref(card->categories);
- card->categories = NULL;
- if (g_value_get_string (value))
- do_parse_categories(card, (char*)g_value_get_string (value));
- break;
- case PROP_CATEGORY_LIST:
- if (card->categories)
- g_object_unref(card->categories);
- card->categories = E_LIST(g_value_get_object(value));
- if (card->categories)
- g_object_ref(card->categories);
- break;
- case PROP_BIRTH_DATE:
- g_free(card->bday);
- if (g_value_get_pointer (value)) {
- card->bday = g_new (ECardDate, 1);
- memcpy (card->bday, g_value_get_pointer (value), sizeof (ECardDate));
- } else {
- card->bday = NULL;
- }
- break;
- case PROP_URL:
- g_free(card->url);
- card->url = g_strdup(g_value_get_string(value));
- break;
- case PROP_ORG:
- g_free(card->org);
- card->org = g_strdup(g_value_get_string(value));
- break;
- case PROP_ORG_UNIT:
- g_free(card->org_unit);
- card->org_unit = g_strdup(g_value_get_string(value));
- break;
- case PROP_OFFICE:
- g_free(card->office);
- card->office = g_strdup(g_value_get_string(value));
- break;
- case PROP_TITLE:
- g_free(card->title);
- card->title = g_strdup(g_value_get_string(value));
- break;
- case PROP_ROLE:
- g_free(card->role);
- card->role = g_strdup(g_value_get_string(value));
- break;
- case PROP_MANAGER:
- g_free(card->manager);
- card->manager = g_strdup(g_value_get_string(value));
- break;
- case PROP_ASSISTANT:
- g_free(card->assistant);
- card->assistant = g_strdup(g_value_get_string(value));
- break;
- case PROP_NICKNAME:
- g_free(card->nickname);
- card->nickname = g_strdup(g_value_get_string(value));
- break;
- case PROP_SPOUSE:
- g_free(card->spouse);
- card->spouse = g_strdup(g_value_get_string(value));
- break;
- case PROP_ANNIVERSARY:
- g_free(card->anniversary);
- if (g_value_get_pointer (value)) {
- card->anniversary = g_new (ECardDate, 1);
- memcpy (card->anniversary, g_value_get_pointer (value), sizeof (ECardDate));
- } else {
- card->anniversary = NULL;
- }
- break;
- case PROP_MAILER:
- g_free(card->mailer);
- card->mailer = g_strdup(g_value_get_string(value));
- break;
- case PROP_CALURI:
- g_free(card->caluri);
- card->caluri = g_strdup(g_value_get_string(value));
- break;
- case PROP_FBURL:
- g_free(card->fburl);
- card->fburl = g_strdup(g_value_get_string(value));
- break;
- case PROP_ICSCALENDAR:
- g_free(card->icscalendar);
- card->icscalendar = g_strdup(g_value_get_string(value));
- break;
- case PROP_NOTE:
- g_free (card->note);
- card->note = g_strdup(g_value_get_string(value));
- break;
- case PROP_RELATED_CONTACTS:
- g_free (card->related_contacts);
- card->related_contacts = g_strdup(g_value_get_string(value));
- break;
- case PROP_WANTS_HTML:
- card->wants_html = g_value_get_boolean (value);
- card->wants_html_set = TRUE;
- break;
- case PROP_ARBITRARY:
- if (card->arbitrary)
- g_object_unref(card->arbitrary);
- card->arbitrary = E_LIST(g_value_get_pointer(value));
- if (card->arbitrary)
- g_object_ref(card->arbitrary);
- break;
- case PROP_ID:
- g_free(card->id);
- card->id = g_strdup(g_value_get_string(value));
- if (card->id == NULL)
- card->id = g_strdup ("");
- break;
- case PROP_LAST_USE:
- g_free(card->last_use);
- if (g_value_get_pointer (value)) {
- card->last_use = g_new (ECardDate, 1);
- memcpy (card->last_use, g_value_get_pointer (value), sizeof (ECardDate));
- } else {
- card->last_use = NULL;
- }
- break;
- case PROP_USE_SCORE:
- card->raw_use_score = g_value_get_float (value);
- break;
- case PROP_EVOLUTION_LIST:
- card->list = g_value_get_boolean (value);
- break;
- case PROP_EVOLUTION_LIST_SHOW_ADDRESSES:
- card->list_show_addresses = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* Get_arg handler for the card */
-static void
-e_card_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- ECard *card;
-
- card = E_CARD (object);
-
- switch (prop_id) {
- case PROP_FILE_AS:
- g_value_set_string (value, card->file_as);
- break;
- case PROP_FULL_NAME:
- g_value_set_string (value, card->fname);
- break;
- case PROP_NAME:
- g_value_set_pointer (value, card->name);
- break;
- case PROP_ADDRESS:
- if (!card->address)
- card->address = e_list_new((EListCopyFunc) e_card_delivery_address_ref,
- (EListFreeFunc) e_card_delivery_address_unref,
- NULL);
- g_value_set_object (value, card->address);
- break;
- case PROP_ADDRESS_LABEL:
- if (!card->address_label)
- card->address_label = e_list_new((EListCopyFunc) e_card_address_label_ref,
- (EListFreeFunc) e_card_address_label_unref,
- NULL);
- g_value_set_object (value, card->address_label);
- break;
- case PROP_PHONE:
- if (!card->phone)
- card->phone = e_list_new((EListCopyFunc) e_card_phone_ref,
- (EListFreeFunc) e_card_phone_unref,
- NULL);
- g_value_set_object (value, card->phone);
- break;
- case PROP_EMAIL:
- if (!card->email)
- card->email = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
- g_value_set_object (value, card->email);
- break;
- case PROP_CATEGORIES:
- {
- int i;
- char ** strs;
- int length;
- EIterator *iterator;
- if (!card->categories)
- card->categories = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
- length = e_list_length(card->categories);
- strs = g_new(char *, length + 1);
- for (iterator = e_list_get_iterator(card->categories), i = 0; e_iterator_is_valid(iterator); e_iterator_next(iterator), i++) {
- strs[i] = (char *)e_iterator_get(iterator);
- }
- strs[i] = 0;
- g_value_set_string_take_ownership(value, g_strjoinv(", ", strs));
- g_free(strs);
- }
- break;
- case PROP_CATEGORY_LIST:
- if (!card->categories)
- card->categories = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
- g_value_set_object (value, card->categories);
- break;
- case PROP_BIRTH_DATE:
- g_value_set_pointer (value, card->bday);
- break;
- case PROP_URL:
- g_value_set_string (value, card->url);
- break;
- case PROP_ORG:
- g_value_set_string (value, card->org);
- break;
- case PROP_ORG_UNIT:
- g_value_set_string (value, card->org_unit);
- break;
- case PROP_OFFICE:
- g_value_set_string (value, card->office);
- break;
- case PROP_TITLE:
- g_value_set_string (value, card->title);
- break;
- case PROP_ROLE:
- g_value_set_string (value, card->role);
- break;
- case PROP_MANAGER:
- g_value_set_string (value, card->manager);
- break;
- case PROP_ASSISTANT:
- g_value_set_string (value, card->assistant);
- break;
- case PROP_NICKNAME:
- g_value_set_string (value, card->nickname);
- break;
- case PROP_SPOUSE:
- g_value_set_string (value, card->spouse);
- break;
- case PROP_ANNIVERSARY:
- g_value_set_pointer (value, card->anniversary);
- break;
- case PROP_MAILER:
- g_value_set_string (value, card->mailer);
- break;
- case PROP_CALURI:
- g_value_set_string (value, card->caluri);
- break;
- case PROP_FBURL:
- g_value_set_string (value, card->fburl);
- break;
- case PROP_ICSCALENDAR:
- g_value_set_string (value, card->icscalendar);
- break;
- case PROP_NOTE:
- g_value_set_string (value, card->note);
- break;
- case PROP_RELATED_CONTACTS:
- g_value_set_string (value, card->related_contacts);
- break;
- case PROP_WANTS_HTML:
- g_value_set_boolean (value, card->wants_html);
- break;
- case PROP_WANTS_HTML_SET:
- g_value_set_boolean (value, card->wants_html_set);
- break;
- case PROP_ARBITRARY:
- if (!card->arbitrary)
- card->arbitrary = e_list_new((EListCopyFunc) e_card_arbitrary_ref,
- (EListFreeFunc) e_card_arbitrary_unref,
- NULL);
-
- g_value_set_object (value, card->arbitrary);
- break;
- case PROP_ID:
- g_value_set_string (value, card->id);
- break;
- case PROP_LAST_USE:
- g_value_set_pointer (value, card->last_use);
- break;
- case PROP_USE_SCORE:
- g_value_set_float (value, e_card_get_use_score (card));
- break;
- case PROP_EVOLUTION_LIST:
- g_value_set_boolean (value, card->list);
- break;
- case PROP_EVOLUTION_LIST_SHOW_ADDRESSES:
- g_value_set_boolean (value, card->list_show_addresses);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-/**
- * e_card_init:
- */
-static void
-e_card_init (ECard *card)
-{
- card->id = g_strdup("");
-
- card->file_as = NULL;
- card->fname = NULL;
- card->name = NULL;
- card->bday = NULL;
- card->email = NULL;
- card->phone = NULL;
- card->address = NULL;
- card->address_label = NULL;
- card->url = NULL;
- card->org = NULL;
- card->org_unit = NULL;
- card->office = NULL;
- card->title = NULL;
- card->role = NULL;
- card->manager = NULL;
- card->assistant = NULL;
- card->nickname = NULL;
- card->spouse = NULL;
- card->anniversary = NULL;
- card->mailer = NULL;
- card->caluri = NULL;
- card->fburl = NULL;
- card->icscalendar = NULL;
- card->note = NULL;
- card->related_contacts = NULL;
- card->categories = NULL;
- card->wants_html = FALSE;
- card->wants_html_set = FALSE;
- card->list = FALSE;
- card->list_show_addresses = FALSE;
- card->arbitrary = NULL;
- card->last_use = NULL;
- card->raw_use_score = 0;
-}
-
-GList *
-e_card_load_cards_from_file_with_default_charset(const char *filename, const char *default_charset)
-{
- VObject *vobj = Parse_MIME_FromFileName((char *) filename);
- GList *list = NULL;
- while(vobj) {
- VObject *next;
- ECard *card = g_object_new (E_TYPE_CARD, NULL);
- parse(card, vobj, default_charset);
- next = nextVObjectInList(vobj);
- cleanVObject(vobj);
- vobj = next;
- list = g_list_prepend(list, card);
- }
- list = g_list_reverse(list);
- return list;
-}
-
-GList *
-e_card_load_cards_from_file(const char *filename)
-{
- return e_card_load_cards_from_file_with_default_charset (filename, "UTF-8");
-}
-
-GList *
-e_card_load_cards_from_string_with_default_charset(const char *str, const char *default_charset)
-{
- VObject *vobj = Parse_MIME(str, strlen (str));
- GList *list = NULL;
- while(vobj) {
- VObject *next;
- ECard *card = g_object_new (E_TYPE_CARD, NULL);
- parse(card, vobj, default_charset);
- next = nextVObjectInList(vobj);
- cleanVObject(vobj);
- vobj = next;
- list = g_list_prepend(list, card);
- }
- list = g_list_reverse(list);
- return list;
-}
-
-GList *
-e_card_load_cards_from_string(const char *str)
-{
- return e_card_load_cards_from_string_with_default_charset (str, "UTF-8");
-}
-
-void
-e_card_free_empty_lists (ECard *card)
-{
- if (card->address && e_list_length (card->address) == 0) {
- g_object_unref (card->address);
- card->address = NULL;
- }
-
- if (card->address_label && e_list_length (card->address_label) == 0) {
- g_object_unref (card->address_label);
- card->address_label = NULL;
- }
-
- if (card->phone && e_list_length (card->phone) == 0) {
- g_object_unref (card->phone);
- card->phone = NULL;
- }
-
- if (card->email && e_list_length (card->email) == 0) {
- g_object_unref (card->email);
- card->email = NULL;
- }
-
- if (card->categories && e_list_length (card->categories) == 0) {
- g_object_unref (card->categories);
- card->categories = NULL;
- }
-
- if (card->arbitrary && e_list_length (card->arbitrary) == 0) {
- g_object_unref (card->arbitrary);
- card->arbitrary = NULL;
- }
-}
-
-static void
-assign_string(VObject *vobj, const char *default_charset, char **string)
-{
- int type = vObjectValueType(vobj);
- char *str;
- const char *charset = default_charset;
- char *charset_buf = NULL;
- VObject *charset_obj;
-
- if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) {
- switch (vObjectValueType (charset_obj)) {
- case VCVT_STRINGZ:
- charset = vObjectStringZValue(charset_obj);
- break;
- case VCVT_USTRINGZ:
- charset_buf = fakeCString (vObjectUStringZValue (charset_obj));
- charset = charset_buf;
- break;
- }
- }
-
- switch(type) {
- case VCVT_STRINGZ:
- if (strcmp (charset, "UTF-8"))
- *string = e_utf8_from_charset_string (charset, vObjectStringZValue(vobj));
- else
- *string = g_strdup(vObjectStringZValue(vobj));
- break;
- case VCVT_USTRINGZ:
- str = fakeCString (vObjectUStringZValue (vobj));
- if (strcmp (charset, "UTF-8"))
- *string = e_utf8_from_charset_string (charset, str);
- else
- *string = g_strdup(str);
- free(str);
- break;
- default:
- *string = g_strdup("");
- break;
- }
-
- if (charset_buf) {
- free (charset_buf);
- }
-}
-
-
-ECardDate
-e_card_date_from_string (const char *str)
-{
- ECardDate date;
- int length;
-
- date.year = 0;
- date.month = 0;
- date.day = 0;
-
- length = strlen(str);
-
- if (length == 10 ) {
- date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111;
- date.month = str[5] * 10 + str[6] - '0' * 11;
- date.day = str[8] * 10 + str[9] - '0' * 11;
- } else if ( length == 8 ) {
- date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111;
- date.month = str[4] * 10 + str[5] - '0' * 11;
- date.day = str[6] * 10 + str[7] - '0' * 11;
- }
-
- return date;
-}
-
-char *
-e_v_object_get_child_value(VObject *vobj, char *name, const char *default_charset)
-{
- char *ret_val;
- VObjectIterator iterator;
- char *charset_buf = NULL;
- VObject *charset_obj;
-
- if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) {
- switch (vObjectValueType (charset_obj)) {
- case VCVT_STRINGZ:
- default_charset = vObjectStringZValue(charset_obj);
- break;
- case VCVT_USTRINGZ:
- charset_buf = fakeCString (vObjectUStringZValue (charset_obj));
- default_charset = charset_buf;
- break;
- }
- }
-
- initPropIterator(&iterator, vobj);
- while(moreIteration (&iterator)) {
- VObject *attribute = nextVObject(&iterator);
- const char *id = vObjectName(attribute);
- if ( ! strcmp(id, name) ) {
- assign_string(attribute, default_charset, &ret_val);
- return ret_val;
- }
- }
- if (charset_buf)
- free (charset_buf);
-
- return NULL;
-}
-
-static struct {
- char *id;
- ECardPhoneFlags flag;
-} phone_pairs[] = {
- { VCPreferredProp, E_CARD_PHONE_PREF },
- { VCWorkProp, E_CARD_PHONE_WORK },
- { VCHomeProp, E_CARD_PHONE_HOME },
- { VCVoiceProp, E_CARD_PHONE_VOICE },
- { VCFaxProp, E_CARD_PHONE_FAX },
- { VCMessageProp, E_CARD_PHONE_MSG },
- { VCCellularProp, E_CARD_PHONE_CELL },
- { VCPagerProp, E_CARD_PHONE_PAGER },
- { VCBBSProp, E_CARD_PHONE_BBS },
- { VCModemProp, E_CARD_PHONE_MODEM },
- { VCCarProp, E_CARD_PHONE_CAR },
- { VCISDNProp, E_CARD_PHONE_ISDN },
- { VCVideoProp, E_CARD_PHONE_VIDEO },
- { "X-EVOLUTION-ASSISTANT", E_CARD_PHONE_ASSISTANT },
- { "X-EVOLUTION-CALLBACK", E_CARD_PHONE_CALLBACK },
- { "X-EVOLUTION-RADIO", E_CARD_PHONE_RADIO },
- { "X-EVOLUTION-TELEX", E_CARD_PHONE_TELEX },
- { "X-EVOLUTION-TTYTDD", E_CARD_PHONE_TTYTDD },
-};
-
-static ECardPhoneFlags
-get_phone_flags (VObject *vobj)
-{
- ECardPhoneFlags ret = 0;
- int i;
-
- for (i = 0; i < sizeof(phone_pairs) / sizeof(phone_pairs[0]); i++) {
- if (isAPropertyOf (vobj, phone_pairs[i].id)) {
- ret |= phone_pairs[i].flag;
- }
- }
-
- return ret;
-}
-
-static void
-set_phone_flags (VObject *vobj, ECardPhoneFlags flags)
-{
- int i;
-
- for (i = 0; i < sizeof(phone_pairs) / sizeof(phone_pairs[0]); i++) {
- if (flags & phone_pairs[i].flag) {
- addProp (vobj, phone_pairs[i].id);
- }
- }
-}
-
-static struct {
- char *id;
- ECardAddressFlags flag;
-} addr_pairs[] = {
- { VCDomesticProp, E_CARD_ADDR_DOM },
- { VCInternationalProp, E_CARD_ADDR_INTL },
- { VCPostalProp, E_CARD_ADDR_POSTAL },
- { VCParcelProp, E_CARD_ADDR_PARCEL },
- { VCHomeProp, E_CARD_ADDR_HOME },
- { VCWorkProp, E_CARD_ADDR_WORK },
- { "PREF", E_CARD_ADDR_DEFAULT },
-};
-
-static ECardAddressFlags
-get_address_flags (VObject *vobj)
-{
- ECardAddressFlags ret = 0;
- int i;
-
- for (i = 0; i < sizeof(addr_pairs) / sizeof(addr_pairs[0]); i++) {
- if (isAPropertyOf (vobj, addr_pairs[i].id)) {
- ret |= addr_pairs[i].flag;
- }
- }
-
- return ret;
-}
-
-static void
-set_address_flags (VObject *vobj, ECardAddressFlags flags)
-{
- int i;
-
- for (i = 0; i < sizeof(addr_pairs) / sizeof(addr_pairs[0]); i++) {
- if (flags & addr_pairs[i].flag) {
- addProp (vobj, addr_pairs[i].id);
- }
- }
-}
-
-gboolean
-e_card_evolution_list (ECard *card)
-{
- g_return_val_if_fail (card && E_IS_CARD (card), FALSE);
- return card->list;
-}
-
-gboolean
-e_card_evolution_list_show_addresses (ECard *card)
-{
- g_return_val_if_fail (card && E_IS_CARD (card), FALSE);
- return card->list_show_addresses;
-}
-
-typedef struct _CardLoadData CardLoadData;
-struct _CardLoadData {
- gchar *card_id;
- ECardCallback cb;
- gpointer closure;
-};
-
-static void
-get_card_cb (EBook *book, EBookStatus status, ECard *card, gpointer closure)
-{
- CardLoadData *data = (CardLoadData *) closure;
-
- if (data->cb != NULL) {
- if (status == E_BOOK_STATUS_SUCCESS)
- data->cb (card, data->closure);
- else
- data->cb (NULL, data->closure);
- }
-
- g_free (data->card_id);
- g_free (data);
-}
-
-static void
-card_load_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- CardLoadData *data = (CardLoadData *) closure;
-
- if (status == E_BOOK_STATUS_SUCCESS)
- e_book_get_card (book, data->card_id, get_card_cb, closure);
- else {
- data->cb (NULL, data->closure);
- g_free (data->card_id);
- g_free (data);
- }
-}
-
-void
-e_card_load_uri (const gchar *book_uri, const gchar *uid, ECardCallback cb, gpointer closure)
-{
- CardLoadData *data;
- EBook *book;
-
- data = g_new (CardLoadData, 1);
- data->card_id = g_strdup (uid);
- data->cb = cb;
- data->closure = closure;
-
- book = e_book_new ();
- e_book_load_uri (book, book_uri, card_load_cb, data);
-}
diff --git a/addressbook/backend/ebook/e-card.h b/addressbook/backend/ebook/e-card.h
deleted file mode 100644
index 8819966d5b..0000000000
--- a/addressbook/backend/ebook/e-card.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Arturo Espinosa
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 1999 The Free Software Foundation
- */
-
-#ifndef __E_CARD_H__
-#define __E_CARD_H__
-
-#include <time.h>
-#include <glib-object.h>
-#include <stdio.h>
-#include <ebook/e-card-types.h>
-#include <e-util/e-list.h>
-
-#define E_TYPE_CARD (e_card_get_type ())
-#define E_CARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CARD, ECard))
-#define E_CARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CARD, ECardClass))
-#define E_IS_CARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CARD))
-#define E_IS_CARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD))
-#define E_CARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CARD, ECardClass))
-
-typedef struct _ECard ECard;
-typedef struct _ECardClass ECardClass;
-
-struct _EBook; /* Forward reference */
-
-struct _ECard {
- GObject object;
- char *id;
-
- struct _EBook *book; /* The EBook this card is from. */
-
- char *file_as; /* The File As field. */
- char *fname; /* The full name. */
- ECardName *name; /* The structured name. */
- EList *address; /* Delivery addresses (ECardDeliveryAddress *) */
- EList *address_label; /* Delivery address labels
- * (ECardAddrLabel *) */
-
- EList *phone; /* Phone numbers (ECardPhone *) */
- EList *email; /* Email addresses (char *) */
- char *url; /* The person's web page. */
-
- ECardDate *bday; /* The person's birthday. */
-
- char *note;
-
-
- char *org; /* The person's organization. */
- char *org_unit; /* The person's organization unit. */
- char *office; /* The person's office. */
- char *role; /* The person's role w/in his org */
- char *title; /* The person's title w/in his org */
-
- char *manager;
- char *assistant;
-
- char *nickname; /* The person's nickname */
-
- char *spouse; /* The person's spouse. */
- ECardDate *anniversary; /* The person's anniversary. */
-
- char *mailer; /* Mailer */
-
- char *caluri; /* Calendar URI */
- char *fburl; /* Free Busy URL */
- char *icscalendar; /* Default server calendar */
-
- gint timezone; /* number of minutes from UTC as an int */
-
- ECardDate *last_use;
- float raw_use_score;
-
- char *related_contacts; /* EDestinationV (serialized) of related contacts. */
-
- EList *categories; /* Categories. */
-
- EList *arbitrary; /* Arbitrary fields. */
-
-
-
- guint32 wants_html : 1; /* Wants html mail. */
- guint32 wants_html_set : 1; /* Wants html mail. */
- guint32 list : 1; /* If the card corresponds to a contact list */
- guint32 list_show_addresses : 1; /* Whether to show the addresses
- in the To: or Bcc: field */
-
-#if 0
- ECardPhoto *logo; /* This person's org's logo. */
-
- ECardPhoto *photo; /* A photo of the person. */
-
- ECard *agent; /* A person who sereves as this
- guy's agent/secretary/etc. */
-
- ECardSound *sound;
-
- ECardKey *key; /* The person's public key. */
- ECardTimeZone *timezn; /* The person's time zone. */
- ECardGeoPos *geopos; /* The person's long/lat. */
-
- ECardRev *rev; /* The time this card was last
- modified. */
-
- EList xtension;
-#endif
-};
-
-struct _ECardClass {
- GObjectClass parent_class;
- GHashTable *attribute_jump_table;
-};
-
-
-/* Simple functions */
-ECard *e_card_new (const char *vcard); /* Assumes utf8 */
-ECard *e_card_new_with_default_charset (const char *vcard,
- const char *default_charset);
-const char *e_card_get_id (ECard *card);
-void e_card_set_id (ECard *card,
- const char *character);
-
-struct _EBook *e_card_get_book (ECard *card);
-void e_card_set_book (ECard *card,
- struct _EBook *book);
-char *e_card_get_vcard (ECard *card);
-char *e_card_get_vcard_assume_utf8 (ECard *card);
-char *e_card_list_get_vcard (const GList *list);
-ECard *e_card_duplicate (ECard *card);
-float e_card_get_use_score (ECard *card);
-void e_card_touch (ECard *card);
-
-/* Evolution List convenience functions */
-/* used for encoding uids in email addresses */
-gboolean e_card_evolution_list (ECard *card);
-gboolean e_card_evolution_list_show_addresses (ECard *card);
-
-/* ECardPhone manipulation */
-ECardPhone *e_card_phone_new (void);
-ECardPhone *e_card_phone_copy (const ECardPhone *phone);
-ECardPhone *e_card_phone_ref (const ECardPhone *phone);
-void e_card_phone_unref (ECardPhone *phone);
-
-/* ECardDeliveryAddress manipulation */
-ECardDeliveryAddress *e_card_delivery_address_new (void);
-ECardDeliveryAddress *e_card_delivery_address_copy (const ECardDeliveryAddress *addr);
-ECardDeliveryAddress *e_card_delivery_address_ref (const ECardDeliveryAddress *addr);
-void e_card_delivery_address_unref (ECardDeliveryAddress *addr);
-gboolean e_card_delivery_address_is_empty (const ECardDeliveryAddress *addr);
-char *e_card_delivery_address_to_string (const ECardDeliveryAddress *addr);
-ECardDeliveryAddress *e_card_delivery_address_from_label (const ECardAddrLabel *label);
-ECardAddrLabel *e_card_delivery_address_to_label (const ECardDeliveryAddress *addr);
-
-/* ECardAddrLabel manipulation */
-ECardAddrLabel *e_card_address_label_new (void);
-ECardAddrLabel *e_card_address_label_copy (const ECardAddrLabel *addr);
-ECardAddrLabel *e_card_address_label_ref (const ECardAddrLabel *addr);
-void e_card_address_label_unref (ECardAddrLabel *addr);
-
-/* ECardName manipulation */
-ECardName *e_card_name_new (void);
-ECardName *e_card_name_copy (const ECardName *name);
-ECardName *e_card_name_ref (const ECardName *name);
-void e_card_name_unref (ECardName *name);
-char *e_card_name_to_string (const ECardName *name);
-ECardName *e_card_name_from_string (const char *full_name);
-
-/* ECardDate */
-ECardDate e_card_date_from_string (const gchar *str);
-gchar *e_card_date_to_string (ECardDate *dt);
-
-/* ECardArbitrary manipulation */
-ECardArbitrary *e_card_arbitrary_new (void);
-ECardArbitrary *e_card_arbitrary_copy (const ECardArbitrary *arbitrary);
-ECardArbitrary *e_card_arbitrary_ref (const ECardArbitrary *arbitrary);
-void e_card_arbitrary_unref (ECardArbitrary *arbitrary);
-
-/* ECard email manipulation */
-gboolean e_card_email_match_string (const ECard *card,
- const gchar *str);
-gint e_card_email_find_number (const ECard *card,
- const gchar *email);
-
-/* Specialized functionality */
-GList *e_card_load_cards_from_file (const char *filename);
-GList *e_card_load_cards_from_file_with_default_charset (const char *filename,
- const char *default_charset);
-GList *e_card_load_cards_from_string (const char *str);
-GList *e_card_load_cards_from_string_with_default_charset (const char *str,
- const char *default_charset);
-void e_card_free_empty_lists (ECard *card);
-
-/* Getting ECards via their URIs */
-typedef void (*ECardCallback) (ECard *card, gpointer closure);
-void e_card_load_uri (const gchar *book_uri,
- const gchar *uid,
- ECardCallback cb,
- gpointer closure);
-
-
-GType e_card_get_type (void);
-
-#endif /* ! __E_CARD_H__ */
diff --git a/addressbook/backend/ebook/e-contact.c b/addressbook/backend/ebook/e-contact.c
new file mode 100644
index 0000000000..ce92b31f71
--- /dev/null
+++ b/addressbook/backend/ebook/e-contact.c
@@ -0,0 +1,1288 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-contact.c
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Chris Toshok (toshok@ximian.com)
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnomevfs/gnome-vfs-mime-utils.h>
+#include "e-contact.h"
+#include "e-book.h"
+#include "e-util/ename/e-name-western.h"
+
+struct _EContactPrivate {
+};
+
+#define E_CONTACT_FIELD_TYPE_STRING 0x00000001 /* used for simple single valued attributes */
+/*E_CONTACT_FIELD_TYPE_FLOAT*/
+#define E_CONTACT_FIELD_TYPE_LIST 0x00000002 /* used for multivalued single attributes - the elements are of type char* */
+#define E_CONTACT_FIELD_TYPE_MULTI 0x00000004 /* used for multivalued attributes - the elements are of type EVCardAttribute */
+#define E_CONTACT_FIELD_TYPE_STRUCT 0x00000008 /* used for structured types (N and ADR properties, in particular) */
+#define E_CONTACT_FIELD_TYPE_BOOLEAN 0x00000010 /* used for boolean types (WANTS_HTML) */
+
+#define E_CONTACT_FIELD_TYPE_SYNTHETIC 0x10000000 /* used when there isn't a corresponding vcard field (such as email_1) */
+#define E_CONTACT_FIELD_TYPE_LIST_ELEM 0x20000000 /* used when a synthetic attribute is a numbered list element */
+#define E_CONTACT_FIELD_TYPE_MULTI_ELEM 0x40000000 /* used when we're looking for the nth attribute where more than 1 can be present in the vcard */
+#define E_CONTACT_FIELD_TYPE_ATTR_TYPE 0x80000000 /* used when a synthetic attribute is flagged with a TYPE= that we'll be looking for */
+
+typedef struct {
+ guint32 t;
+
+ EContactField field_id;
+ const char *vcard_field_name;
+ const char *field_name; /* non translated */
+ const char *pretty_name; /* translated */
+
+ gboolean read_only;
+
+ int list_elem;
+ const char *attr_type1;
+ const char *attr_type2;
+
+ void* (*struct_getter)(EContact *contact, EVCardAttribute *attribute);
+ void (*struct_setter)(EContact *contact, EVCardAttribute *attribute, void *data);
+
+} EContactFieldInfo;
+
+static void* photo_getter (EContact *contact, EVCardAttribute *attr);
+static void photo_setter (EContact *contact, EVCardAttribute *attr, void *data);
+static void* fn_getter (EContact *contact, EVCardAttribute *attr);
+static void fn_setter (EContact *contact, EVCardAttribute *attr, void *data);
+static void* n_getter (EContact *contact, EVCardAttribute *attr);
+static void n_setter (EContact *contact, EVCardAttribute *attr, void *data);
+static void* adr_getter (EContact *contact, EVCardAttribute *attr);
+static void adr_setter (EContact *contact, EVCardAttribute *attr, void *data);
+static void* date_getter (EContact *contact, EVCardAttribute *attr);
+static void date_setter (EContact *contact, EVCardAttribute *attr, void *data);
+
+#define STRING_FIELD(id,vc,n,pn,ro) { E_CONTACT_FIELD_TYPE_STRING, (id), (vc), (n), (pn), (ro) }
+#define BOOLEAN_FIELD(id,vc,n,pn,ro) { E_CONTACT_FIELD_TYPE_BOOLEAN, (id), (vc), (n), (pn), (ro) }
+#define LIST_FIELD(id,vc,n,pn,ro) { E_CONTACT_FIELD_TYPE_LIST, (id), (vc), (n), (pn), (ro) }
+#define MULTI_LIST_FIELD(id,vc,n,pn,ro) { E_CONTACT_FIELD_TYPE_MULTI, (id), (vc), (n), (pn), (ro) }
+#define STRUCT_FIELD(id,vc,n,pn,ro,get,set) { E_CONTACT_FIELD_TYPE_STRUCT, (id), (vc), (n), (pn), (ro), -1, NULL, NULL, (get), (set) }
+#define LIST_ELEM_STR_FIELD(id,vc,n,pn,ro,nm) { E_CONTACT_FIELD_TYPE_LIST_ELEM | E_CONTACT_FIELD_TYPE_SYNTHETIC | E_CONTACT_FIELD_TYPE_STRING, (id), (vc), (n), (pn), (ro), (nm) }
+#define MULTI_ELEM_STR_FIELD(id,vc,n,pn,ro,nm) { E_CONTACT_FIELD_TYPE_MULTI_ELEM | E_CONTACT_FIELD_TYPE_SYNTHETIC | E_CONTACT_FIELD_TYPE_STRING, (id), (vc), (n), (pn), (ro), (nm) }
+#define ATTR_TYPE_STR_FIELD(id,vc,n,pn,ro,at1,nth) { E_CONTACT_FIELD_TYPE_ATTR_TYPE | E_CONTACT_FIELD_TYPE_SYNTHETIC | E_CONTACT_FIELD_TYPE_STRING, (id), (vc), (n), (pn), (ro), (nth), (at1), NULL }
+#define ATTR2_TYPE_STR_FIELD(id,vc,n,pn,ro,at1,at2,nth) { E_CONTACT_FIELD_TYPE_ATTR_TYPE | E_CONTACT_FIELD_TYPE_SYNTHETIC | E_CONTACT_FIELD_TYPE_STRING, (id), (vc), (n), (pn), (ro), (nth), (at1), (at2) }
+#define ATTR_TYPE_STRUCT_FIELD(id,vc,n,pn,ro,at,get,set) { E_CONTACT_FIELD_TYPE_ATTR_TYPE | E_CONTACT_FIELD_TYPE_SYNTHETIC | E_CONTACT_FIELD_TYPE_STRUCT, (id), (vc), (n), (pn), (ro), 0, (at), NULL, (get), (set) }
+
+static EContactFieldInfo field_info[] = {
+ STRING_FIELD (E_CONTACT_UID, EVC_UID, "id", N_("Unique ID"), FALSE),
+ STRING_FIELD (E_CONTACT_FILE_AS, EVC_X_FILE_AS, "file_as", N_("File As"), FALSE),
+
+ /* Name fields */
+ /* FN isn't really a structured field - we use a getter/setter
+ so we can set the N property (since evo 1.4 works fine with
+ vcards that don't even have a N attribute. *sigh*) */
+ STRUCT_FIELD (E_CONTACT_FULL_NAME, EVC_FN, "full_name", N_("Full Name"), FALSE, fn_getter, fn_setter),
+ STRUCT_FIELD (E_CONTACT_NAME, EVC_N, "name", N_("Name"), FALSE, n_getter, n_setter),
+ LIST_ELEM_STR_FIELD (E_CONTACT_GIVEN_NAME, EVC_N, "given_name", N_("Given Name"), FALSE, 1),
+ LIST_ELEM_STR_FIELD (E_CONTACT_FAMILY_NAME, EVC_N, "family_name", N_("Family Name"), FALSE, 0),
+ STRING_FIELD (E_CONTACT_NICKNAME, EVC_NICKNAME, "nickname", N_("Nickname"), FALSE),
+
+ /* Address fields */
+ MULTI_LIST_FIELD (E_CONTACT_ADDRESS, EVC_ADR, "address", N_("Address List"), FALSE),
+ ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_HOME, EVC_ADR, "address_home", N_("Home Address"), FALSE, "HOME", adr_getter, adr_setter),
+ ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_WORK, EVC_ADR, "address_work", N_("Work Address"), FALSE, "WORK", adr_getter, adr_setter),
+ ATTR_TYPE_STRUCT_FIELD (E_CONTACT_ADDRESS_OTHER, EVC_ADR, "address_other", N_("Other Address"), FALSE, "OTHER", adr_getter, adr_setter),
+
+ ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_HOME, EVC_LABEL, "address_label_home", N_("Home Address Label"), FALSE, "HOME", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_WORK, EVC_LABEL, "address_label_work", N_("Work Address Label"), FALSE, "WORK", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_ADDRESS_LABEL_OTHER, EVC_LABEL, "address_label_other", N_("Other Address Label"), FALSE, "OTHER", 0),
+
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_ASSISTANT, EVC_TEL, "assistant_phone", N_("Assistant Phone"), FALSE, "X-EVOLUTION-ASSISTANT", 0),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_BUSINESS, EVC_TEL, "business_phone", N_("Business Phone"), FALSE, "WORK", "VOICE", 0),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_BUSINESS_2, EVC_TEL, "business_phone_2", N_("Business Phone 2"), FALSE, "WORK", "VOICE", 1),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_BUSINESS_FAX, EVC_TEL, "business_fax", N_("Business Fax"), FALSE, "WORK", "FAX", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_CALLBACK, EVC_TEL, "callback_phone", N_("Callback Phone"), FALSE, "X-EVOLUTION-CALLBACK", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_CAR, EVC_TEL, "car_phone", N_("Car Phone"), FALSE, "CAR", 0),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_COMPANY, EVC_TEL, "company_phone", N_("Company Phone"), FALSE, "WORK", "VOICE", 2),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_HOME, EVC_TEL, "home_phone", N_("Home Phone"), FALSE, "HOME", "VOICE", 0),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_HOME_2, EVC_TEL, "home_phone_2", N_("Home Phone 2"), FALSE, "HOME", "VOICE", 1),
+ ATTR2_TYPE_STR_FIELD (E_CONTACT_PHONE_HOME_FAX, EVC_TEL, "home_fax", N_("Home Fax"), FALSE, "HOME", "FAX", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_ISDN, EVC_TEL, "isdn_phone", N_("ISDN"), FALSE, "ISDN", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_MOBILE, EVC_TEL, "mobile_phone", N_("Mobile Phone"), FALSE, "CELL", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_OTHER, EVC_TEL, "other_phone", N_("Other Phone"), FALSE, "VOICE", 0), /* XXX */
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_OTHER_FAX, EVC_TEL, "other_fax", N_("Other Fax"), FALSE, "FAX", 0), /* XXX */
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_PAGER, EVC_TEL, "pager", N_("Pager"), FALSE, "PAGER", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_PRIMARY, EVC_TEL, "primary_phone", N_("Primary Phone"), FALSE, "PREF", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_RADIO, EVC_TEL, "radio", N_("Radio"), FALSE, "X-EVOLUTION-RADIO", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_TELEX, EVC_TEL, "telex", N_("Telex"), FALSE, "X-EVOLUTION-TELEX", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_PHONE_TTYTDD, EVC_TEL, "tty", N_("TTY"), FALSE, "X-EVOLUTION-TTYTDD", 0),
+
+ /* Email fields */
+ MULTI_LIST_FIELD (E_CONTACT_EMAIL, EVC_EMAIL, "email", N_("Email List"), FALSE),
+ MULTI_ELEM_STR_FIELD (E_CONTACT_EMAIL_1, EVC_EMAIL, "email_1", N_("Email 1"), FALSE, 0),
+ MULTI_ELEM_STR_FIELD (E_CONTACT_EMAIL_2, EVC_EMAIL, "email_2", N_("Email 2"), FALSE, 1),
+ MULTI_ELEM_STR_FIELD (E_CONTACT_EMAIL_3, EVC_EMAIL, "email_3", N_("Email 3"), FALSE, 2),
+ STRING_FIELD (E_CONTACT_MAILER, EVC_MAILER, "mailer", N_("Mailer"), FALSE),
+ BOOLEAN_FIELD (E_CONTACT_WANTS_HTML, EVC_X_WANTS_HTML, "wants_html", N_("Wants HTML Mail"), FALSE),
+
+ /* Instant messaging fields */
+ LIST_FIELD (E_CONTACT_IM_AIM, EVC_X_AIM, "im_aim", N_("AIM Screen Name List"), FALSE),
+ LIST_FIELD (E_CONTACT_IM_JABBER, EVC_X_JABBER, "im_jabber", N_("Jabber Id List"), FALSE),
+ LIST_FIELD (E_CONTACT_IM_YAHOO, EVC_X_YAHOO, "im_yahoo", N_("Yahoo! Screen Name List"), FALSE),
+ LIST_FIELD (E_CONTACT_IM_MSN, EVC_X_MSN, "im_msn", N_("MSN Screen Name List"), FALSE),
+ LIST_FIELD (E_CONTACT_IM_ICQ, EVC_X_ICQ, "im_icq", N_("ICQ Id List"), FALSE),
+
+ /* Organizational fields */
+ LIST_ELEM_STR_FIELD (E_CONTACT_ORG, EVC_ORG, "org", N_("Organization"), FALSE, 0),
+ LIST_ELEM_STR_FIELD (E_CONTACT_ORG_UNIT, EVC_ORG, "org_unit", N_("Organizational Unit"), FALSE, 1),
+ LIST_ELEM_STR_FIELD (E_CONTACT_OFFICE, EVC_ORG, "office", N_("Office"), FALSE, 2),
+
+ STRING_FIELD (E_CONTACT_TITLE, EVC_TITLE, "title", N_("Title"), FALSE),
+ STRING_FIELD (E_CONTACT_ROLE, EVC_ROLE, "role", N_("Role"), FALSE),
+ STRING_FIELD (E_CONTACT_MANAGER, EVC_X_MANAGER, "manager", N_("Manager"), FALSE),
+ STRING_FIELD (E_CONTACT_ASSISTANT, EVC_X_ASSISTANT, "assistant", N_("Assistant"), FALSE),
+
+ /* Web fields */
+ STRING_FIELD (E_CONTACT_HOMEPAGE_URL, EVC_URL, "homepage_url", N_("Homepage URL"), FALSE),
+ STRING_FIELD (E_CONTACT_BLOG_URL, EVC_X_BLOG_URL, "blog_url", N_("Weblog URL"), FALSE),
+
+ /* Photo/Logo */
+ STRUCT_FIELD (E_CONTACT_PHOTO, EVC_PHOTO, "photo", N_("Photo"), FALSE, photo_getter, photo_setter),
+ STRUCT_FIELD (E_CONTACT_LOGO, EVC_LOGO, "logo", N_("Logo"), FALSE, photo_getter, photo_setter),
+
+ /* Contact categories */
+#if notyet
+ LIST_FIELD (E_CONTACT_CATEGORY_LIST, EVC_CATEGORIES, "category_list", N_("Category List"), FALSE),
+ SYNTH_STR_FIELD (E_CONTACT_CATEGORIES, "categories", N_("Categories"), FALSE),
+#else
+ STRING_FIELD (E_CONTACT_CATEGORIES, EVC_CATEGORIES, "categories", N_("Categories"), FALSE),
+#endif
+
+ /* Collaboration fields */
+ STRING_FIELD (E_CONTACT_CALENDAR_URI, EVC_CALURI, "caluri", N_("Calendar URI"), FALSE),
+ STRING_FIELD (E_CONTACT_FREEBUSY_URL, EVC_FBURL, "fburl", N_("Free/Busy URL"), FALSE),
+ STRING_FIELD (E_CONTACT_ICS_CALENDAR, EVC_ICSCALENDAR, "icscalendar", N_("ICS Calendar"), FALSE),
+
+ /* Misc fields */
+ STRING_FIELD (E_CONTACT_SPOUSE, EVC_X_SPOUSE, "spouse", N_("Spouse's Name"), FALSE),
+ STRING_FIELD (E_CONTACT_NOTE, EVC_NOTE, "note", N_("Note"), FALSE),
+
+ STRUCT_FIELD (E_CONTACT_BIRTH_DATE, EVC_BDAY, "birth_date", N_("Birth Date"), FALSE, date_getter, date_setter),
+ STRUCT_FIELD (E_CONTACT_ANNIVERSARY, EVC_BDAY, "anniversary", N_("Anniversary"), FALSE, date_getter, date_setter),
+
+ BOOLEAN_FIELD (E_CONTACT_IS_LIST, EVC_X_LIST, "list", N_("List"), FALSE),
+ BOOLEAN_FIELD (E_CONTACT_LIST_SHOW_ADDRESSES, EVC_X_LIST_SHOW_ADDRESSES, "list_show_addresses", N_("List Show Addresses"), FALSE)
+};
+
+#undef LIST_ELEM_STR_FIELD
+#undef STRING_FIELD
+#undef SYNTH_STR_FIELD
+#undef LIST_FIELD
+#undef STRUCT_FIELD
+
+static GObjectClass *parent_class;
+
+static void e_contact_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void e_contact_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void
+e_contact_dispose (GObject *object)
+{
+ EContact *ec = E_CONTACT (object);
+
+ if (!ec->priv)
+ return;
+
+ /* XXX free instance specific stuff */
+
+ g_free (ec->priv);
+ ec->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+e_contact_class_init (EContactClass *klass)
+{
+ GObjectClass *object_class;
+ int i;
+
+ object_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_ref (E_TYPE_VCARD);
+
+ object_class->dispose = e_contact_dispose;
+ object_class->set_property = e_contact_set_property;
+ object_class->get_property = e_contact_get_property;
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i ++) {
+ GParamSpec *pspec = NULL;
+ if (field_info[i].t & E_CONTACT_FIELD_TYPE_STRING)
+ pspec = g_param_spec_string (field_info[i].field_name,
+ _(field_info[i].pretty_name),
+ "" /* XXX blurb */,
+ NULL,
+ field_info[i].read_only ? G_PARAM_READABLE : G_PARAM_READWRITE);
+ else if (field_info[i].t & E_CONTACT_FIELD_TYPE_BOOLEAN)
+ pspec = g_param_spec_boolean (field_info[i].field_name,
+ _(field_info[i].pretty_name),
+ "" /* XXX blurb */,
+ FALSE,
+ field_info[i].read_only ? G_PARAM_READABLE : G_PARAM_READWRITE);
+ else
+ pspec = g_param_spec_pointer (field_info[i].field_name,
+ _(field_info[i].pretty_name),
+ "" /* XXX blurb */,
+ field_info[i].read_only ? G_PARAM_READABLE : G_PARAM_READWRITE);
+
+ g_object_class_install_property (object_class, field_info[i].field_id,
+ pspec);
+ }
+}
+
+static void
+e_contact_init (EContact *ec)
+{
+ ec->priv = g_new0 (EContactPrivate, 1);
+}
+
+GType
+e_contact_get_type (void)
+{
+ static GType contact_type = 0;
+
+ if (!contact_type) {
+ static const GTypeInfo contact_info = {
+ sizeof (EContactClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) e_contact_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EContact),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) e_contact_init,
+ };
+
+ contact_type = g_type_register_static (E_TYPE_VCARD, "EContact", &contact_info, 0);
+ }
+
+ return contact_type;
+}
+
+static EVCardAttribute*
+e_contact_get_first_attr (EContact *contact, const char *attr_name)
+{
+ GList *attrs, *l;
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, attr_name))
+ return attr;
+ }
+
+ return NULL;
+}
+
+
+
+static void*
+photo_getter (EContact *contact, EVCardAttribute *attr)
+{
+ if (attr) {
+ GList *values = e_vcard_attribute_get_values_decoded (attr);
+
+ if (values && values->data) {
+ GString *s = values->data;
+ EContactPhoto *photo = g_new (EContactPhoto, 1);
+
+ photo->length = s->len;
+ photo->data = g_malloc (photo->length);
+ memcpy (photo->data, s->str, photo->length);
+
+ return photo;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+photo_setter (EContact *contact, EVCardAttribute *attr, void *data)
+{
+ EContactPhoto *photo = data;
+ const char *mime_type;
+ char *image_type = "X-EVOLUTION-UNKNOWN";
+
+ e_vcard_attribute_add_param_with_value (attr,
+ e_vcard_attribute_param_new (EVC_ENCODING),
+ "b");
+
+ mime_type = gnome_vfs_get_mime_type_for_data (photo->data, photo->length);
+ if (!strcmp (mime_type, "image/gif"))
+ image_type = "GIF";
+ else if (!strcmp (mime_type, "image/jpeg"))
+ image_type = "JPEG";
+ else if (!strcmp (mime_type, "image/png"))
+ image_type = "PNG";
+ else if (!strcmp (mime_type, "image/tiff"))
+ image_type = "TIFF";
+ /* i have no idea what these last 2 are.. :) */
+ else if (!strcmp (mime_type, "image/ief"))
+ image_type = "IEF";
+ else if (!strcmp (mime_type, "image/cgm"))
+ image_type = "CGM";
+
+ e_vcard_attribute_add_param_with_value (attr,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ image_type);
+
+ printf ("adding photo of type `%s' of length %d\n", image_type, photo->length);
+ e_vcard_attribute_add_value_decoded (attr, photo->data, photo->length);
+}
+
+
+static void*
+fn_getter (EContact *contact, EVCardAttribute *attr)
+{
+ if (attr) {
+ GList *p = e_vcard_attribute_get_values (attr);
+
+ return g_strdup (p && p->data ? p->data : "");
+ }
+ else
+ return NULL;
+}
+
+static void
+fn_setter (EContact *contact, EVCardAttribute *attr, void *data)
+{
+ e_vcard_attribute_add_value (attr, (char*)data);
+
+ attr = e_contact_get_first_attr (contact, EVC_N);
+ if (!attr) {
+ EContactName *name = e_contact_name_from_string ((char*)data);
+
+ attr = e_vcard_attribute_new (NULL, EVC_N);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+
+ /* call the setter directly */
+ n_setter (contact, attr, name);
+
+ e_contact_name_free (name);
+ }
+}
+
+
+
+static void*
+n_getter (EContact *contact, EVCardAttribute *attr)
+{
+ EContactName *name = g_new0 (EContactName, 1);
+ if (attr) {
+ GList *p = e_vcard_attribute_get_values (attr);
+
+ name->family = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ name->given = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ name->additional = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ name->prefixes = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ name->suffixes = g_strdup (p && p->data ? p->data : "");
+ }
+
+ return name;
+}
+
+static void
+n_setter (EContact *contact, EVCardAttribute *attr, void *data)
+{
+ EContactName *name = data;
+
+ e_vcard_attribute_add_value (attr, name->family);
+ e_vcard_attribute_add_value (attr, name->given);
+ e_vcard_attribute_add_value (attr, name->additional);
+ e_vcard_attribute_add_value (attr, name->prefixes);
+ e_vcard_attribute_add_value (attr, name->suffixes);
+
+ /* now find the attribute for FileAs. if it's not present, fill it in */
+ attr = e_contact_get_first_attr (contact, EVC_X_FILE_AS);
+ if (!attr) {
+ char *strings[3], **stringptr;
+ char *string;
+ attr = e_vcard_attribute_new (NULL, EVC_X_FILE_AS);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+
+ stringptr = strings;
+ if (name->family && *name->family)
+ *(stringptr++) = name->family;
+ if (name->given && *name->given)
+ *(stringptr++) = name->given;
+ *stringptr = NULL;
+ string = g_strjoinv(", ", strings);
+
+ e_vcard_attribute_add_value (attr, string);
+ g_free (string);
+ }
+
+}
+
+
+
+static void*
+adr_getter (EContact *contact, EVCardAttribute *attr)
+{
+ if (attr) {
+ GList *p = e_vcard_attribute_get_values (attr);
+ EContactAddress *addr = g_new (EContactAddress, 1);
+
+ addr->po = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->ext = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->street = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->locality = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->region = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->code = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+ addr->country = g_strdup (p && p->data ? p->data : ""); if (p) p = p->next;
+
+ return addr;
+ }
+
+ return NULL;
+}
+
+static void
+adr_setter (EContact *contact, EVCardAttribute *attr, void *data)
+{
+ /* XXX */
+ g_assert_not_reached ();
+}
+
+
+
+static void*
+date_getter (EContact *contact, EVCardAttribute *attr)
+{
+ if (attr) {
+ GList *p = e_vcard_attribute_get_values (attr);
+ EContactDate *date = e_contact_date_from_string (p && p->data ? (char*)p->data : "");
+
+ return date;
+ }
+
+ return NULL;
+}
+
+static void
+date_setter (EContact *contact, EVCardAttribute *attr, void *data)
+{
+ EContactDate *date = data;
+ char *str = e_contact_date_to_string (date);
+
+ e_vcard_attribute_add_value (attr, str);
+ g_free (str);
+}
+
+
+
+/* Set_arg handler for the contact */
+static void
+e_contact_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EContact *contact = E_CONTACT (object);
+ int i;
+ EContactFieldInfo *info = NULL;
+
+ if (prop_id < 1 || prop_id >= E_CONTACT_FIELD_LAST) {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ return;
+ }
+
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i++) {
+ if (field_info[i].field_id == prop_id) {
+ info = &field_info[i];
+ break;
+ }
+ }
+
+ if (!info) {
+ g_warning ("unknown field %d", prop_id);
+ return;
+ }
+
+ if (info->t & E_CONTACT_FIELD_TYPE_MULTI) {
+ GList *new_values = g_value_get_pointer (value);
+ GList *l;
+
+ /* first we remove all attributes of the type we're
+ adding, then add new ones based on the values that
+ are passed in */
+ e_vcard_remove_attributes (E_VCARD (contact), NULL, info->vcard_field_name);
+
+ for (l = new_values; l; l = l->next)
+ e_vcard_add_attribute_with_value (E_VCARD (contact),
+ e_vcard_attribute_new (NULL, info->vcard_field_name),
+ (char*)l->data);
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_SYNTHETIC) {
+ if (info->t & E_CONTACT_FIELD_TYPE_MULTI_ELEM) {
+ /* XXX this is kinda broken - we don't insert
+ insert padding elements if, e.g. the user
+ sets email 3 when email 1 and 2 don't
+ exist. But, if we *did* pad the lists we'd
+ end up with empty items in the vcard. I
+ dunno which is worse. */
+ EVCardAttribute *attr = NULL;
+ gboolean found = FALSE;
+ int num_left = info->list_elem;
+ GList *attrs = e_vcard_get_attributes (E_VCARD (contact));
+ GList *l;
+
+ for (l = attrs; l; l = l->next) {
+ const char *name, *group;
+
+ attr = l->data;
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, info->vcard_field_name)) {
+ if (num_left-- == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ /* we found it, overwrite it */
+ e_vcard_attribute_remove_values (attr);
+ }
+ else {
+ /* we didn't find it - add a new attribute */
+ attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ }
+
+ e_vcard_attribute_add_value (attr, g_value_get_string (value));
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_ATTR_TYPE) {
+ /* XXX this is kinda broken - we don't insert
+ insert padding elements if, e.g. the user
+ sets email 3 when email 1 and 2 don't
+ exist. But, if we *did* pad the lists we'd
+ end up with empty items in the vcard. I
+ dunno which is worse. */
+ EVCardAttribute *attr = NULL;
+ gboolean found = FALSE;
+ int num_left = info->list_elem;
+ GList *attrs = e_vcard_get_attributes (E_VCARD (contact));
+ GList *l;
+ const char *sval = g_value_get_string (value);
+
+ for (l = attrs; l && !found; l = l->next) {
+ const char *name, *group;
+ gboolean found_needed1, found_needed2;
+
+ if (!info->attr_type1)
+ found_needed1 = TRUE;
+ else
+ found_needed1 = FALSE;
+
+ if (!info->attr_type2)
+ found_needed2 = TRUE;
+ else
+ found_needed2 = FALSE;
+
+ attr = l->data;
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, info->vcard_field_name)) {
+ GList *params;
+
+ for (params = e_vcard_attribute_get_params (attr); params; params = params->next) {
+ EVCardAttributeParam *param = params->data;
+ const char *name = e_vcard_attribute_param_get_name (param);
+
+ if (!strcasecmp (name, EVC_TYPE)) {
+ GList *values = e_vcard_attribute_param_get_values (param);
+ if (values && values->data) {
+ if (!found_needed1 && !strcasecmp ((char*)values->data, info->attr_type1))
+ found_needed1 = TRUE;
+ else if (!found_needed2 && !strcasecmp ((char*)values->data, info->attr_type2))
+ found_needed2 = TRUE;
+ }
+ }
+
+ if (found_needed1 && found_needed2) {
+ if (num_left-- == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (found) {
+ /* we found it, overwrite it */
+ e_vcard_attribute_remove_values (attr);
+ }
+ else {
+ /* we didn't find it - add a new attribute */
+ attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ if (info->attr_type1)
+ e_vcard_attribute_add_param_with_value (attr, e_vcard_attribute_param_new (EVC_TYPE),
+ info->attr_type1);
+ if (info->attr_type2)
+ e_vcard_attribute_add_param_with_value (attr, e_vcard_attribute_param_new (EVC_TYPE),
+ info->attr_type2);
+ }
+
+ if (sval && *sval)
+ e_vcard_attribute_add_value (attr, sval);
+ else
+ e_vcard_remove_attribute (E_VCARD (contact), attr);
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_LIST_ELEM) {
+ EVCardAttribute *attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ GList *values;
+ GList *p;
+ const char *sval = g_value_get_string (value);
+
+ if (!attr) {
+ if (!sval || !*sval)
+ return;
+
+ printf ("adding new %s\n", info->vcard_field_name);
+
+ attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ }
+
+ values = e_vcard_attribute_get_values (attr);
+ p = g_list_nth (values, info->list_elem);
+
+ if (p) {
+ g_free (p->data);
+ p->data = g_strdup (g_value_get_string (value));
+ }
+ else {
+ /* there weren't enough elements in the list, pad it */
+ int count = info->list_elem - g_list_length (values);
+
+ while (count--)
+ e_vcard_attribute_add_value (attr, "");
+
+ e_vcard_attribute_add_value (attr, g_value_get_string (value));
+ }
+
+ }
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_BOOLEAN) {
+ EVCardAttribute *attr;
+
+ /* first we search for an attribute we can overwrite */
+ attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ if (attr) {
+ printf ("setting %s to `%s'\n", info->vcard_field_name, g_value_get_string (value));
+ e_vcard_attribute_remove_values (attr);
+ e_vcard_attribute_add_value (attr, g_value_get_boolean (value) ? "TRUE" : "FALSE");
+ }
+ else {
+ /* and if we don't find one we create a new attribute */
+ e_vcard_add_attribute_with_value (E_VCARD (contact),
+ e_vcard_attribute_new (NULL, info->vcard_field_name),
+ g_value_get_boolean (value) ? "TRUE" : "FALSE");
+ }
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_STRING) {
+ EVCardAttribute *attr;
+ const char *sval = g_value_get_string (value);
+
+ /* first we search for an attribute we can overwrite */
+ attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ if (attr) {
+ printf ("setting %s to `%s'\n", info->vcard_field_name, sval);
+ e_vcard_attribute_remove_values (attr);
+ if (sval)
+ e_vcard_attribute_add_value (attr, sval);
+ }
+ else if (sval) {
+ /* and if we don't find one we create a new attribute */
+ e_vcard_add_attribute_with_value (E_VCARD (contact),
+ e_vcard_attribute_new (NULL, info->vcard_field_name),
+ g_value_get_string (value));
+ }
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_STRUCT) {
+ EVCardAttribute *attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ void *data = g_value_get_pointer (value);
+
+ if (attr) {
+ printf ("overwriting existing %s\n", info->vcard_field_name);
+ /* remove all existing values and parameters.
+ the setter will add the correct ones */
+ e_vcard_attribute_remove_values (attr);
+ e_vcard_attribute_remove_params (attr);
+ }
+ else {
+ printf ("adding new %s\n", info->vcard_field_name);
+ attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
+
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ }
+
+ info->struct_setter (contact, attr, data);
+ }
+ else {
+ g_warning ("unhandled attribute `%s'", info->vcard_field_name);
+ }
+}
+
+static GList *
+e_contact_get_email_list (EContact *contact)
+{
+ GList *rv = NULL;
+ GList *attrs, *l;
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, EVC_EMAIL)) {
+ GList *v = e_vcard_attribute_get_values (attr);
+
+ rv = g_list_append (rv, v ? g_strdup (v->data) : NULL);
+ }
+ }
+
+ return rv;
+}
+
+static EVCardAttribute *
+e_contact_find_attribute_with_types (EContact *contact, const char *attr_name, const char *type_needed1, const char *type_needed2, int nth)
+{
+ GList *l, *attrs;
+ gboolean found_needed1, found_needed2;
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ if (!type_needed1)
+ found_needed1 = TRUE;
+ else
+ found_needed1 = FALSE;
+
+ if (!type_needed2)
+ found_needed2 = TRUE;
+ else
+ found_needed2 = FALSE;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, attr_name)) {
+ GList *params;
+
+ for (params = e_vcard_attribute_get_params (attr); params; params = params->next) {
+ EVCardAttributeParam *param = params->data;
+ const char *name = e_vcard_attribute_param_get_name (param);
+
+ if (!strcasecmp (name, EVC_TYPE)) {
+ GList *values = e_vcard_attribute_param_get_values (param);
+ if (values && values->data) {
+ if (!found_needed1 && !strcasecmp ((char*)values->data, type_needed1))
+ found_needed1 = TRUE;
+ else if (!found_needed2 && !strcasecmp ((char*)values->data, type_needed2))
+ found_needed2 = TRUE;
+ }
+ }
+
+ if (found_needed1 && found_needed2) {
+ if (nth-- == 0)
+ return attr;
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static void
+e_contact_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EContact *contact = E_CONTACT (object);
+ int i;
+ EContactFieldInfo *info = NULL;
+
+ if (prop_id < 1 || prop_id >= E_CONTACT_FIELD_LAST) {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ return;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i++) {
+ if (field_info[i].field_id == prop_id) {
+ info = &field_info[i];
+ break;
+ }
+ }
+
+ if (!info) {
+ g_warning ("unknown field %d", prop_id);
+ return;
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_BOOLEAN) {
+ EVCardAttribute *attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ gboolean rv = FALSE;
+
+ if (attr) {
+ GList *v = e_vcard_attribute_get_values (attr);
+ rv = v && v->data && !strcasecmp ((char*)v->data, "true");
+ }
+
+ g_value_set_boolean (value, rv);
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_LIST) {
+ EVCardAttribute *attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+
+ if (attr)
+ g_value_set_pointer (value, e_vcard_attribute_get_values (attr));
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_LIST_ELEM) {
+ if (info->t & E_CONTACT_FIELD_TYPE_STRING) {
+ GList *attrs, *l;
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, info->vcard_field_name)) {
+ GList *v;
+ int count;
+
+ v = e_vcard_attribute_get_values (attr);
+ count = info->list_elem;
+
+ v = g_list_nth (v, info->list_elem);
+
+ g_value_set_string (value, v ? v->data : NULL);
+ }
+ }
+ }
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_MULTI_ELEM) {
+ if (info->t & E_CONTACT_FIELD_TYPE_STRING) {
+ GList *attrs, *l;
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, info->vcard_field_name)) {
+ GList *v;
+ int count;
+
+ v = e_vcard_attribute_get_values (attr);
+ count = info->list_elem;
+
+ v = g_list_nth (v, info->list_elem);
+
+ g_value_set_string (value, v ? v->data : NULL);
+ }
+ }
+ }
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_ATTR_TYPE) {
+ EVCardAttribute *attr = e_contact_find_attribute_with_types (contact, info->vcard_field_name, info->attr_type1, info->attr_type2, info->list_elem);
+
+ if (info->t & E_CONTACT_FIELD_TYPE_STRING) {
+ if (attr) {
+ GList *p = e_vcard_attribute_get_values (attr);
+ char *rv = p->data;
+
+ g_value_set_string (value, rv);
+ }
+ else {
+ g_value_set_string (value, NULL);
+ }
+ }
+ else { /* struct */
+ gpointer rv = info->struct_getter (contact, attr);
+
+ g_value_set_pointer (value, rv);
+ }
+
+ }
+ else if (info->t & E_CONTACT_FIELD_TYPE_STRUCT) {
+ EVCardAttribute *attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+ void *rv = NULL;
+
+ if (attr)
+ rv = info->struct_getter (contact, attr);
+
+ g_value_set_pointer (value, rv);
+ }
+
+ else if (info->t & E_CONTACT_FIELD_TYPE_SYNTHETIC) {
+ switch (info->field_id) {
+ default:
+ g_warning ("unhandled synthetic field 0x%02x", info->field_id);
+ }
+ }
+ else {
+ GList *attrs, *l;
+ GList *rv = NULL; /* used for multi attribute lists */
+
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+
+ for (l = attrs; l; l = l->next) {
+ EVCardAttribute *attr = l->data;
+ const char *name, *group;
+
+ group = e_vcard_attribute_get_group (attr);
+ name = e_vcard_attribute_get_name (attr);
+
+ /* all the attributes we care about should be in group "" */
+ if ((!group || !*group) && !strcasecmp (name, info->vcard_field_name)) {
+ GList *v;
+ v = e_vcard_attribute_get_values (attr);
+
+ if (info->t & E_CONTACT_FIELD_TYPE_STRING) {
+ g_value_set_string (value, v ? v->data : NULL);
+ }
+ else {
+ rv = g_list_append (rv, v ? g_strdup (v->data) : NULL);
+
+ g_value_set_pointer (value, rv);
+ }
+ }
+ }
+ }
+}
+
+
+
+EContact*
+e_contact_new (void)
+{
+ return e_contact_new_from_vcard ("");
+}
+
+EContact*
+e_contact_new_from_vcard (const char *vcard)
+{
+ EContact *contact = g_object_new (E_TYPE_CONTACT, NULL);
+
+ e_vcard_construct (E_VCARD (contact), vcard);
+
+ return contact;
+}
+
+EContact*
+e_contact_duplicate (EContact *contact)
+{
+ char *vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ EContact *c = e_contact_new_from_vcard (vcard);
+
+ g_free (vcard);
+
+ return c;
+}
+
+const char *
+e_contact_field_name (EContactField field_id)
+{
+ int i;
+
+ g_return_val_if_fail (field_id >= 1 && field_id <= E_CONTACT_FIELD_LAST, "");
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i ++) {
+ if (field_id == field_info[i].field_id)
+ return field_info[i].field_name;
+ }
+
+ g_warning ("unknown field id %d", field_id);
+ return "";
+}
+
+const char *
+e_contact_pretty_name (EContactField field_id)
+{
+ int i;
+
+ g_return_val_if_fail (field_id >= 1 && field_id <= E_CONTACT_FIELD_LAST, "");
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i ++) {
+ if (field_id == field_info[i].field_id)
+ return _(field_info[i].pretty_name);
+ }
+
+ g_warning ("unknown field id %d", field_id);
+ return "";
+}
+
+EContactField
+e_contact_field_id (const char *field_name)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (field_info); i ++) {
+ if (!strcmp (field_info[i].field_name, field_name))
+ return field_info[i].field_id;
+ }
+
+ g_warning ("unknown field name `%s'", field_name);
+ return 0;
+}
+
+gpointer
+e_contact_get (EContact *contact, EContactField field_id)
+{
+ gpointer value;
+
+ g_return_val_if_fail (contact && E_IS_CONTACT (contact), NULL);
+ g_return_val_if_fail (field_id >= 1 && field_id <= E_CONTACT_FIELD_LAST, NULL);
+
+ g_object_get (contact,
+ e_contact_field_name (field_id), &value,
+ NULL);
+
+ return value;
+}
+
+/* XXX this won't work for structure/list types... */
+static void
+free_const_data (gpointer data, GObject *where_object_was)
+{
+ g_free (data);
+}
+
+const gpointer
+e_contact_get_const (EContact *contact, EContactField field_id)
+{
+ gpointer value;
+
+ g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
+ g_return_val_if_fail (field_id >= 1 && field_id <= E_CONTACT_FIELD_LAST, NULL);
+
+ value = e_contact_get (contact, field_id);
+
+ g_object_weak_ref (G_OBJECT (contact), free_const_data, value);
+
+ return value;
+}
+
+void
+e_contact_set (EContact *contact, EContactField field_id, gpointer value)
+{
+ printf ("e_contact_set (%p, %d, %p)\n", contact, field_id, value);
+
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
+ g_return_if_fail (field_id >= 1 && field_id <= E_CONTACT_FIELD_LAST);
+
+ g_object_set (contact,
+ e_contact_field_name (field_id), value,
+ NULL);
+}
+
+EContactName*
+e_contact_name_new ()
+{
+ return g_new0 (EContactName, 1);
+}
+
+char *
+e_contact_name_to_string(const EContactName *name)
+{
+ char *strings[6], **stringptr = strings;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ if (name->prefixes && *name->prefixes)
+ *(stringptr++) = name->prefixes;
+ if (name->given && *name->given)
+ *(stringptr++) = name->given;
+ if (name->additional && *name->additional)
+ *(stringptr++) = name->additional;
+ if (name->family && *name->family)
+ *(stringptr++) = name->family;
+ if (name->suffixes && *name->suffixes)
+ *(stringptr++) = name->suffixes;
+ *stringptr = NULL;
+ return g_strjoinv(" ", strings);
+}
+
+EContactName*
+e_contact_name_from_string (const char *name_str)
+{
+ EContactName *name = e_contact_name_new();
+ ENameWestern *western = e_name_western_parse (name_str);
+
+ name->prefixes = g_strdup (western->prefix);
+ name->given = g_strdup (western->first );
+ name->additional = g_strdup (western->middle);
+ name->family = g_strdup (western->last );
+ name->suffixes = g_strdup (western->suffix);
+
+ e_name_western_free(western);
+
+ return name;
+}
+
+EContactName*
+e_contact_name_copy (EContactName *n)
+{
+ EContactName *name = e_contact_name_new();
+
+ name->prefixes = g_strdup (n->prefixes);
+ name->given = g_strdup (n->given);
+ name->additional = g_strdup (n->additional);
+ name->family = g_strdup (n->family);
+ name->suffixes = g_strdup (n->suffixes);
+
+ return name;
+}
+
+void
+e_contact_name_free (EContactName *name)
+{
+ if (!name)
+ return;
+
+ g_free (name->family);
+ g_free (name->given);
+ g_free (name->additional);
+ g_free (name->prefixes);
+ g_free (name->suffixes);
+
+ g_free (name);
+}
+
+EContactDate*
+e_contact_date_new (void)
+{
+ return g_new0 (EContactDate, 1);
+}
+
+EContactDate*
+e_contact_date_from_string (const char *str)
+{
+ EContactDate* date = e_contact_date_new();
+ int length;
+
+ length = strlen(str);
+
+ if (length == 10 ) {
+ date->year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111;
+ date->month = str[5] * 10 + str[6] - '0' * 11;
+ date->day = str[8] * 10 + str[9] - '0' * 11;
+ } else if ( length == 8 ) {
+ date->year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111;
+ date->month = str[4] * 10 + str[5] - '0' * 11;
+ date->day = str[6] * 10 + str[7] - '0' * 11;
+ }
+
+ return date;
+}
+
+char *
+e_contact_date_to_string (EContactDate *dt)
+{
+ if (dt)
+ return g_strdup_printf ("%04d-%02d-%02d",
+ CLAMP(dt->year, 1000, 9999),
+ CLAMP(dt->month, 1, 12),
+ CLAMP(dt->day, 1, 31));
+ else
+ return NULL;
+}
+
+void
+e_contact_date_free (EContactDate *dt)
+{
+ g_free (dt);
+}
+
+
+void
+e_contact_photo_free (EContactPhoto *photo)
+{
+ if (!photo)
+ return;
+
+ g_free (photo->data);
+ g_free (photo);
+}
+
+void
+e_contact_address_free (EContactAddress *address)
+{
+ if (!address)
+ return;
+
+ g_free (address->address_format);
+ g_free (address->po);
+ g_free (address->ext);
+ g_free (address->street);
+ g_free (address->locality);
+ g_free (address->region);
+ g_free (address->code);
+ g_free (address->country);
+
+ g_free (address);
+}
diff --git a/addressbook/backend/ebook/e-contact.h b/addressbook/backend/ebook/e-contact.h
new file mode 100644
index 0000000000..8de02caa5f
--- /dev/null
+++ b/addressbook/backend/ebook/e-contact.h
@@ -0,0 +1,227 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ */
+
+#ifndef __E_CONTACT_H__
+#define __E_CONTACT_H__
+
+#include <time.h>
+#include <glib-object.h>
+#include <stdio.h>
+#include <ebook/e-vcard.h>
+
+#define E_TYPE_CONTACT (e_contact_get_type ())
+#define E_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT, EContact))
+#define E_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT, EContactClass))
+#define E_IS_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT))
+#define E_IS_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT))
+#define E_CONTACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CONTACT, EContactClass))
+
+typedef struct _EContact EContact;
+typedef struct _EContactClass EContactClass;
+typedef struct _EContactPrivate EContactPrivate;
+
+typedef enum {
+
+ E_CONTACT_UID = 1, /* string field */
+ E_CONTACT_FILE_AS, /* string field */
+
+ /* Name fields */
+ E_CONTACT_FULL_NAME, /* string field */
+ E_CONTACT_GIVEN_NAME, /* synthetic string field */
+ E_CONTACT_FAMILY_NAME, /* synthetic string field */
+ E_CONTACT_NICKNAME, /* string field */
+
+ /* Email fields */
+ E_CONTACT_EMAIL_1, /* synthetic string field */
+ E_CONTACT_EMAIL_2, /* synthetic string field */
+ E_CONTACT_EMAIL_3, /* synthetic string field */
+
+ E_CONTACT_MAILER, /* string field */
+
+ /* Address Labels */
+ E_CONTACT_ADDRESS_LABEL_HOME, /* synthetic string field */
+ E_CONTACT_ADDRESS_LABEL_WORK, /* synthetic string field */
+ E_CONTACT_ADDRESS_LABEL_OTHER, /* synthetic string field */
+
+ /* Phone fields */
+ E_CONTACT_PHONE_ASSISTANT,
+ E_CONTACT_PHONE_BUSINESS,
+ E_CONTACT_PHONE_BUSINESS_2,
+ E_CONTACT_PHONE_BUSINESS_FAX,
+ E_CONTACT_PHONE_CALLBACK,
+ E_CONTACT_PHONE_CAR,
+ E_CONTACT_PHONE_COMPANY,
+ E_CONTACT_PHONE_HOME,
+ E_CONTACT_PHONE_HOME_2,
+ E_CONTACT_PHONE_HOME_FAX,
+ E_CONTACT_PHONE_ISDN,
+ E_CONTACT_PHONE_MOBILE,
+ E_CONTACT_PHONE_OTHER,
+ E_CONTACT_PHONE_OTHER_FAX,
+ E_CONTACT_PHONE_PAGER,
+ E_CONTACT_PHONE_PRIMARY,
+ E_CONTACT_PHONE_RADIO,
+ E_CONTACT_PHONE_TELEX,
+ E_CONTACT_PHONE_TTYTDD,
+
+ /* Organizational fields */
+ E_CONTACT_ORG, /* string field */
+ E_CONTACT_ORG_UNIT, /* string field */
+ E_CONTACT_OFFICE, /* string field */
+ E_CONTACT_TITLE, /* string field */
+ E_CONTACT_ROLE, /* string field */
+ E_CONTACT_MANAGER, /* string field */
+ E_CONTACT_ASSISTANT, /* string field */
+
+ /* Web fields */
+ E_CONTACT_HOMEPAGE_URL, /* string field */
+ E_CONTACT_BLOG_URL, /* string field */
+
+ /* Contact categories */
+ E_CONTACT_CATEGORIES, /* string field */
+
+ /* Collaboration fields */
+ E_CONTACT_CALENDAR_URI, /* string field */
+ E_CONTACT_FREEBUSY_URL, /* string field */
+ E_CONTACT_ICS_CALENDAR, /* string field */
+
+ /* misc fields */
+ E_CONTACT_SPOUSE, /* string field */
+ E_CONTACT_NOTE, /* string field */
+
+ /* fields used for describing contact lists. a contact list
+ is just a contact with _IS_LIST set to true. the members
+ are listed in the _EMAIL field. */
+ E_CONTACT_IS_LIST, /* boolean field */
+ E_CONTACT_LIST_SHOW_ADDRESSES, /* boolean field */
+
+ /* Instant Messaging fields */
+ E_CONTACT_IM_AIM, /* Multi-valued */
+ E_CONTACT_IM_JABBER, /* Multi-valued */
+ E_CONTACT_IM_YAHOO, /* Multi-valued */
+ E_CONTACT_IM_MSN, /* Multi-valued */
+ E_CONTACT_IM_ICQ, /* Multi-valued */
+
+ /* Address fields */
+ E_CONTACT_ADDRESS, /* Multi-valued structured (EContactAddress) */
+ E_CONTACT_ADDRESS_HOME, /* synthetic structured field (EContactAddress) */
+ E_CONTACT_ADDRESS_WORK, /* synthetic structured field (EContactAddress) */
+ E_CONTACT_ADDRESS_OTHER, /* synthetic structured field (EContactAddress) */
+
+ E_CONTACT_CATEGORY_LIST, /* multi-valued */
+
+ /* Photo/Logo */
+ E_CONTACT_PHOTO, /* structured field (EContactPhoto) */
+ E_CONTACT_LOGO, /* structured field (EContactPhoto) */
+
+ E_CONTACT_NAME, /* structured field (EContactName) */
+ E_CONTACT_EMAIL, /* Multi-valued */
+
+ E_CONTACT_WANTS_HTML, /* boolean field */
+
+ E_CONTACT_BIRTH_DATE, /* structured field (EContactDate) */
+ E_CONTACT_ANNIVERSARY, /* structured field (EContactDate) */
+
+ E_CONTACT_FIELD_LAST,
+
+ /* useful constants */
+ E_CONTACT_LAST_SIMPLE_STRING = E_CONTACT_NOTE,
+ E_CONTACT_FIRST_PHONE_ID = E_CONTACT_PHONE_ASSISTANT,
+ E_CONTACT_LAST_PHONE_ID = E_CONTACT_PHONE_TTYTDD,
+ E_CONTACT_FIRST_EMAIL_ID = E_CONTACT_EMAIL_1,
+ E_CONTACT_LAST_EMAIL_ID = E_CONTACT_EMAIL_3,
+ E_CONTACT_FIRST_ADDRESS_ID = E_CONTACT_ADDRESS_HOME,
+ E_CONTACT_LAST_ADDRESS_ID = E_CONTACT_ADDRESS_OTHER,
+ E_CONTACT_FIRST_LABEL_ID = E_CONTACT_ADDRESS_LABEL_HOME,
+ E_CONTACT_LAST_LABEL_ID = E_CONTACT_ADDRESS_LABEL_OTHER
+
+} EContactField;
+
+typedef struct {
+ char *family;
+ char *given;
+ char *additional;
+ char *prefixes;
+ char *suffixes;
+} EContactName;
+
+typedef struct {
+ int length;
+ char *data;
+} EContactPhoto;
+
+typedef struct {
+ char *address_format; /* the two letter country code that
+ determines the format/meaning of the
+ following fields */
+ char *po;
+ char *ext;
+ char *street;
+ char *locality;
+ char *region;
+ char *code;
+ char *country;
+} EContactAddress;
+
+typedef struct {
+ int year;
+ int month;
+ int day;
+} EContactDate;
+
+struct _EContact {
+ EVCard parent;
+
+ EContactPrivate *priv;
+};
+
+struct _EContactClass {
+ EVCardClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
+};
+
+GType e_contact_get_type (void);
+
+EContact* e_contact_new (void);
+EContact* e_contact_new_from_vcard (const char *vcard);
+
+EContact* e_contact_duplicate (EContact *contact);
+
+gpointer e_contact_get (EContact *contact, EContactField field_id);
+const gpointer e_contact_get_const (EContact *contact, EContactField field_id);
+void e_contact_set (EContact *contact, EContactField field_id, gpointer value);
+
+/* misc functions for structured values */
+EContactDate *e_contact_date_new (void);
+EContactDate *e_contact_date_from_string (const char *str);
+char *e_contact_date_to_string (EContactDate *dt);
+
+EContactName *e_contact_name_new (void);
+char *e_contact_name_to_string (const EContactName *name);
+EContactName *e_contact_name_from_string (const char *name_str);
+EContactName *e_contact_name_copy (EContactName *name);
+
+
+/* destructors for structured values */
+void e_contact_date_free (EContactDate *date);
+void e_contact_name_free (EContactName *name);
+void e_contact_photo_free (EContactPhoto *photo);
+void e_contact_address_free (EContactAddress *address);
+
+
+const char* e_contact_field_name (EContactField field_id);
+const char* e_contact_pretty_name (EContactField field_id);
+EContactField e_contact_field_id (const char *field_name);
+
+#endif /* __E_CONTACT_H__ */
diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h
deleted file mode 100644
index acd6af1bc4..0000000000
--- a/addressbook/backend/ebook/e-destination.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-destination.h
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#ifndef __E_DESTINATION_H__
-#define __E_DESTINATION_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <ebook/e-card.h>
-#include <ebook/e-book.h>
-#include <libxml/tree.h>
-
-#define E_TYPE_DESTINATION (e_destination_get_type ())
-#define E_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_DESTINATION, EDestination))
-#define E_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_DESTINATION, EDestinationClass))
-#define E_IS_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_DESTINATION))
-#define E_IS_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_DESTINATION))
-#define E_DESTINATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_DESTINATION, EDestinationClass))
-
-typedef struct _EDestination EDestination;
-typedef struct _EDestinationClass EDestinationClass;
-
-typedef void (*EDestinationCardCallback) (EDestination *dest, ECard *card, gpointer closure);
-
-struct _EDestinationPrivate;
-
-struct _EDestination {
- GObject object;
-
- struct _EDestinationPrivate *priv;
-};
-
-struct _EDestinationClass {
- GObjectClass parent_class;
-
- void (*changed) (EDestination *dest);
- void (*cardified) (EDestination *dest);
-};
-
-GType e_destination_get_type (void);
-
-
-EDestination *e_destination_new (void);
-void e_destination_changed (EDestination *);
-EDestination *e_destination_copy (const EDestination *);
-void e_destination_clear (EDestination *);
-
-gboolean e_destination_is_empty (const EDestination *);
-gboolean e_destination_is_valid (const EDestination *);
-gboolean e_destination_equal (const EDestination *a, const EDestination *b);
-
-void e_destination_set_card (EDestination *, ECard *card, gint email_num);
-void e_destination_set_book_uri (EDestination *, const gchar *uri);
-void e_destination_set_card_uid (EDestination *, const gchar *uid, gint email_num);
-
-void e_destination_set_name (EDestination *, const gchar *name);
-void e_destination_set_email (EDestination *, const gchar *email);
-
-void e_destination_set_html_mail_pref (EDestination *, gboolean);
-
-gboolean e_destination_contains_card (const EDestination *);
-gboolean e_destination_from_card (const EDestination *);
-
-gboolean e_destination_is_auto_recipient (const EDestination *);
-void e_destination_set_auto_recipient (EDestination *, gboolean value);
-
-void e_destination_use_card (EDestination *, EDestinationCardCallback cb, gpointer closure);
-
-ECard *e_destination_get_card (const EDestination *);
-const gchar *e_destination_get_book_uri (const EDestination *);
-const gchar *e_destination_get_card_uid (const EDestination *);
-gint e_destination_get_email_num (const EDestination *);
-
-const gchar *e_destination_get_name (const EDestination *); /* "Jane Smith" */
-const gchar *e_destination_get_email (const EDestination *); /* "jane@assbarn.com" */
-const gchar *e_destination_get_address (const EDestination *);; /* "Jane Smith <jane@assbarn.com>" (or a comma-sep set of such for a list) */
-
-void e_destination_set_raw (EDestination *, const gchar *free_form_string);
-const gchar *e_destination_get_textrep (const EDestination *, gboolean include_email); /* "Jane Smith" or "jane@assbarn.com" */
-
-gboolean e_destination_is_evolution_list (const EDestination *);
-gboolean e_destination_list_show_addresses (const EDestination *);
-
-/* If true, they want HTML mail. */
-gboolean e_destination_get_html_mail_pref (const EDestination *);
-
-gboolean e_destination_allow_cardification (const EDestination *);
-void e_destination_set_allow_cardification (EDestination *, gboolean);
-void e_destination_cardify (EDestination *, EBook *);
-void e_destination_cardify_delayed (EDestination *, EBook *, gint delay); /* delay < 0: "default" */
-void e_destination_cancel_cardify (EDestination *);
-gboolean e_destination_uncardify (EDestination *);
-
-gboolean e_destination_revert (EDestination *);
-
-gchar *e_destination_get_address_textv (EDestination **);
-
-xmlNodePtr e_destination_xml_encode (const EDestination *dest);
-gboolean e_destination_xml_decode (EDestination *dest, xmlNodePtr node);
-
-gchar *e_destination_export (const EDestination *);
-EDestination *e_destination_import (const gchar *str);
-
-gchar *e_destination_exportv (EDestination **);
-EDestination **e_destination_importv (const gchar *str);
-
-EDestination **e_destination_list_to_vector_sized (GList *, int n);
-EDestination **e_destination_list_to_vector (GList *);
-
-void e_destination_freev (EDestination **);
-
-void e_destination_touch (EDestination *);
-void e_destination_touchv (EDestination **);
-
-
-#endif /* __E_DESTINATION_H__ */
-
diff --git a/addressbook/backend/ebook/e-vcard.c b/addressbook/backend/ebook/e-vcard.c
index 62ebda9349..7ea1d9da84 100644
--- a/addressbook/backend/ebook/e-vcard.c
+++ b/addressbook/backend/ebook/e-vcard.c
@@ -1,5 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* evcard.h
+/* e-vcard.c
*
* Copyright (C) 2003 Ximian, Inc.
*
@@ -22,11 +22,18 @@
#include <glib.h>
#include <stdio.h>
+#include <string.h>
#include <ctype.h>
#include "e-vcard.h"
#define CRLF "\r\n"
+typedef enum {
+ EVC_ENCODING_RAW, /* no encoding */
+ EVC_ENCODING_BASE64, /* base64 */
+ EVC_ENCODING_QP /* quoted-printable */
+} EVCardEncoding;
+
struct _EVCardPrivate {
GList *attributes;
};
@@ -36,6 +43,9 @@ struct _EVCardAttribute {
char *name;
GList *params; /* EVCardParam */
GList *values;
+ GList *decoded_values;
+ EVCardEncoding encoding;
+ gboolean encoding_set;
};
struct _EVCardAttributeParam {
@@ -45,6 +55,12 @@ struct _EVCardAttributeParam {
static GObjectClass *parent_class;
+static void _evc_base64_init(void);
+static size_t _evc_base64_encode_step(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save);
+static size_t _evc_base64_decode_step(unsigned char *in, size_t len, unsigned char *out, int *state, unsigned int *save);
+size_t _evc_base64_decode_simple (char *data, size_t len);
+char *_evc_base64_encode_simple (const char *data, size_t len);
+
static void
e_vcard_dispose (GObject *object)
{
@@ -73,6 +89,8 @@ e_vcard_class_init (EVCardClass *klass)
parent_class = g_type_class_ref (G_TYPE_OBJECT);
object_class->dispose = e_vcard_dispose;
+
+ _evc_base64_init();
}
static void
@@ -229,9 +247,9 @@ read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable
g_warning ("invalid escape, passing it through");
str = g_string_append_c (str, '\\');
str = g_string_append_unichar (str, g_utf8_get_char(lp));
- lp = g_utf8_next_char(lp);
break;
}
+ lp = g_utf8_next_char(lp);
}
else if (*lp == ';') {
e_vcard_attribute_add_value (attr, g_string_free (str, FALSE));
@@ -480,14 +498,16 @@ parse (EVCard *evc, const char *str)
*end = '\0';
}
+#if DEBUG_FOLDING
printf ("BEFORE FOLDING:\n");
printf (str);
-
+#endif
buf = fold_lines (buf);
+#if DEBUG_FOLDING
printf ("\n\nAFTER FOLDING:\n");
printf (buf);
-
+#endif
p = buf;
attr = read_attribute (&p);
@@ -508,6 +528,8 @@ parse (EVCard *evc, const char *str)
if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "end")) {
g_warning ("vcard ended without END:VCARD\n");
}
+
+ g_free (buf);
}
static char*
@@ -517,7 +539,7 @@ escape_string (const char *s)
const char *p;
/* Escape a string as described in RFC2426, section 5 */
- for (p = s; *p; p++) {
+ for (p = s; p && *p; p++) {
switch (*p) {
case '\n':
str = g_string_append (str, "\\n");
@@ -579,24 +601,42 @@ unescape_string (const char *s)
}
#endif
+void
+e_vcard_construct (EVCard *evc, const char *str)
+{
+ if (*str)
+ parse (evc, str);
+}
+
EVCard *
e_vcard_new ()
{
- return g_object_new (E_TYPE_VCARD, NULL);
+ return e_vcard_new_from_string ("");
}
EVCard *
e_vcard_new_from_string (const char *str)
{
- EVCard *evc = e_vcard_new ();
+ EVCard *evc;
- parse (evc, str);
+ g_return_val_if_fail (str, NULL);
+
+ evc = g_object_new (E_TYPE_VCARD, NULL);
+
+ e_vcard_construct (evc, str);
return evc;
}
-char*
-e_vcard_to_string (EVCard *evc)
+static char*
+e_vcard_to_string_vcard_21 (EVCard *evc)
+{
+ g_warning ("need to implement e_vcard_to_string_vcard_21");
+ return g_strdup ("");
+}
+
+static char*
+e_vcard_to_string_vcard_30 (EVCard *evc)
{
GList *l;
GList *v;
@@ -680,6 +720,20 @@ e_vcard_to_string (EVCard *evc)
return g_string_free (str, FALSE);
}
+char*
+e_vcard_to_string (EVCard *evc, EVCardFormat format)
+{
+ switch (format) {
+ case EVC_FORMAT_VCARD_21:
+ return e_vcard_to_string_vcard_21 (evc);
+ case EVC_FORMAT_VCARD_30:
+ return e_vcard_to_string_vcard_30 (evc);
+ default:
+ g_warning ("invalid format specifier passed to e_vcard_to_string");
+ return g_strdup ("");
+ }
+}
+
void
e_vcard_dump_structure (EVCard *evc)
{
@@ -732,24 +786,62 @@ e_vcard_attribute_new (const char *attr_group, const char *attr_name)
void
e_vcard_attribute_free (EVCardAttribute *attr)
{
- GList *p;
-
g_free (attr->group);
g_free (attr->name);
- g_list_foreach (attr->values, (GFunc)g_free, NULL);
- g_list_free (attr->values);
+ e_vcard_attribute_remove_values (attr);
+
+ e_vcard_attribute_remove_params (attr);
+
+ g_free (attr);
+}
+
+EVCardAttribute*
+e_vcard_attribute_copy (EVCardAttribute *attr)
+{
+ EVCardAttribute *a = e_vcard_attribute_new (e_vcard_attribute_get_group (attr),
+ e_vcard_attribute_get_name (attr));
+ GList *p;
+
+ for (p = attr->values; p; p = p->next)
+ e_vcard_attribute_add_value (a, p->data);
+
+ for (p = attr->params; p; p = p->next)
+ e_vcard_attribute_add_param (a, e_vcard_attribute_param_copy (p->data));
+
+ return a;
+}
+
+void
+e_vcard_remove_attributes (EVCard *evc, const char *attr_group, const char *attr_name)
+{
+ GList *attr;
+
+ attr = evc->priv->attributes;
+ while (attr) {
+ GList *next_attr;
+ EVCardAttribute *a = attr->data;
+
+ next_attr = attr->next;
+
+ if (((!attr_group && !a->group) || !g_ascii_strcasecmp (attr_group, a->group)) &&
+ ((!attr_name && !a->name) || !g_ascii_strcasecmp (attr_name, a->name))) {
+
+ /* matches, remove/delete the attribute */
+ evc->priv->attributes = g_list_remove_link (evc->priv->attributes, attr);
- for (p = attr->params; p; p = p->next) {
- EVCardAttributeParam *param = p->data;
+ e_vcard_attribute_free (a);
+ }
- g_free (param->name);
- g_list_foreach (param->values, (GFunc)g_free, NULL);
- g_list_free (param->values);
- g_free (param);
+ attr = next_attr;
}
+}
- g_free (attr);
+void
+e_vcard_remove_attribute (EVCard *evc, EVCardAttribute *attr)
+{
+ evc->priv->attributes = g_list_remove (evc->priv->attributes, attr);
+ e_vcard_attribute_free (attr);
}
void
@@ -791,6 +883,33 @@ e_vcard_attribute_add_value (EVCardAttribute *attr, const char *value)
}
void
+e_vcard_attribute_add_value_decoded (EVCardAttribute *attr, const char *value, int len)
+{
+ switch (attr->encoding) {
+ case EVC_ENCODING_RAW:
+ g_warning ("can't add_value_decoded with an attribute using RAW encoding. you must set the ENCODING parameter first");
+ break;
+ case EVC_ENCODING_BASE64: {
+ char *b64_data = _evc_base64_encode_simple (value, len);
+ GString *decoded = g_string_new_len (value, len);
+
+ /* make sure the decoded list is up to date */
+ e_vcard_attribute_get_values_decoded (attr);
+
+ printf ("base64 encoded value: %s\n", b64_data);
+ printf ("original length: %d\n", len);
+
+ attr->values = g_list_append (attr->values, b64_data);
+ attr->decoded_values = g_list_append (attr->decoded_values, decoded);
+ break;
+ }
+ case EVC_ENCODING_QP:
+ g_warning ("need to implement quoted printable decoding");
+ break;
+ }
+}
+
+void
e_vcard_attribute_add_values (EVCardAttribute *attr,
...)
{
@@ -806,6 +925,21 @@ e_vcard_attribute_add_values (EVCardAttribute *attr,
va_end (ap);
}
+void
+e_vcard_attribute_remove_values (EVCardAttribute *attr)
+{
+ g_list_foreach (attr->values, (GFunc)g_free, NULL);
+ g_list_free (attr->values);
+ attr->values = NULL;
+}
+
+void
+e_vcard_attribute_remove_params (EVCardAttribute *attr)
+{
+ g_list_foreach (attr->params, (GFunc)e_vcard_attribute_param_free, NULL);
+ g_list_free (attr->params);
+ attr->params = NULL;
+}
EVCardAttributeParam*
e_vcard_attribute_param_new (const char *name)
@@ -820,16 +954,55 @@ void
e_vcard_attribute_param_free (EVCardAttributeParam *param)
{
g_free (param->name);
- g_list_foreach (param->values, (GFunc)g_free, NULL);
- g_list_free (param->values);
+
+ e_vcard_attribute_param_remove_values (param);
+
g_free (param);
}
+EVCardAttributeParam*
+e_vcard_attribute_param_copy (EVCardAttributeParam *param)
+{
+ EVCardAttributeParam *p = e_vcard_attribute_param_new (e_vcard_attribute_param_get_name (param));
+ GList *l;
+
+ for (l = param->values; l; l = l->next) {
+ e_vcard_attribute_param_add_value (p, l->data);
+ }
+
+ return p;
+}
+
void
e_vcard_attribute_add_param (EVCardAttribute *attr,
EVCardAttributeParam *param)
{
attr->params = g_list_append (attr->params, param);
+
+ /* we handle our special encoding stuff here */
+
+ if (!g_ascii_strcasecmp (param->name, EVC_ENCODING)) {
+ if (attr->encoding_set) {
+ g_warning ("ENCODING specified twice");
+ return;
+ }
+
+ if (param->values && param->values->data) {
+ if (!g_ascii_strcasecmp ((char*)param->values->data, "b"))
+ attr->encoding = EVC_ENCODING_BASE64;
+ else if (!g_ascii_strcasecmp ((char*)param->values->data, EVC_QUOTEDPRINTABLE))
+ attr->encoding = EVC_ENCODING_QP;
+ else {
+ g_warning ("Unknown value `%s' for ENCODING parameter. values will be treated as raw",
+ (char*)param->values->data);
+ }
+
+ attr->encoding_set = TRUE;
+ }
+ else {
+ g_warning ("ENCODING parameter added with no value");
+ }
+ }
}
void
@@ -882,6 +1055,14 @@ e_vcard_attribute_add_param_with_values (EVCardAttribute *attr,
e_vcard_attribute_add_param (attr, param);
}
+void
+e_vcard_attribute_param_remove_values (EVCardAttributeParam *param)
+{
+ g_list_foreach (param->values, (GFunc)g_free, NULL);
+ g_list_free (param->values);
+ param->values = NULL;
+}
+
GList*
e_vcard_get_attributes (EVCard *evcard)
{
@@ -907,6 +1088,33 @@ e_vcard_attribute_get_values (EVCardAttribute *attr)
}
GList*
+e_vcard_attribute_get_values_decoded (EVCardAttribute *attr)
+{
+ if (!attr->decoded_values) {
+ GList *l;
+ switch (attr->encoding) {
+ case EVC_ENCODING_RAW:
+ for (l = attr->values; l; l = l->next)
+ attr->decoded_values = g_list_append (attr->decoded_values, g_string_new ((char*)l->data));
+ break;
+ case EVC_ENCODING_BASE64:
+ for (l = attr->values; l; l = l->next) {
+ char *decoded = g_strdup ((char*)l->data);
+ int len = _evc_base64_decode_simple (decoded, strlen (decoded));
+ attr->decoded_values = g_list_append (attr->decoded_values, g_string_new_len (decoded, len));
+ g_free (decoded);
+ }
+ break;
+ case EVC_ENCODING_QP:
+ g_warning ("need to implement quoted printable decoding");
+ break;
+ }
+ }
+
+ return attr->decoded_values;
+}
+
+GList*
e_vcard_attribute_get_params (EVCardAttribute *attr)
{
return attr->params;
@@ -923,3 +1131,237 @@ e_vcard_attribute_param_get_values (EVCardAttributeParam *param)
{
return param->values;
}
+
+
+
+/* encoding/decoding stuff ripped from camel-mime-utils.c */
+
+static char *_evc_base64_alphabet =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static unsigned char _evc_base64_rank[256];
+
+static void
+_evc_base64_init(void)
+{
+ int i;
+
+ memset(_evc_base64_rank, 0xff, sizeof(_evc_base64_rank));
+ for (i=0;i<64;i++) {
+ _evc_base64_rank[(unsigned int)_evc_base64_alphabet[i]] = i;
+ }
+ _evc_base64_rank['='] = 0;
+}
+
+/* call this when finished encoding everything, to
+ flush off the last little bit */
+static size_t
+_evc_base64_encode_close(unsigned char *in, size_t inlen, gboolean break_lines, unsigned char *out, int *state, int *save)
+{
+ int c1, c2;
+ unsigned char *outptr = out;
+
+ if (inlen>0)
+ outptr += _evc_base64_encode_step(in, inlen, break_lines, outptr, state, save);
+
+ c1 = ((unsigned char *)save)[1];
+ c2 = ((unsigned char *)save)[2];
+
+#if 0
+ d(printf("mode = %d\nc1 = %c\nc2 = %c\n",
+ (int)((char *)save)[0],
+ (int)((char *)save)[1],
+ (int)((char *)save)[2]));
+#endif
+
+ switch (((char *)save)[0]) {
+ case 2:
+ outptr[2] = _evc_base64_alphabet[ ( (c2 &0x0f) << 2 ) ];
+ g_assert(outptr[2] != 0);
+ goto skip;
+ case 1:
+ outptr[2] = '=';
+ skip:
+ outptr[0] = _evc_base64_alphabet[ c1 >> 2 ];
+ outptr[1] = _evc_base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 )];
+ outptr[3] = '=';
+ outptr += 4;
+ break;
+ }
+ if (break_lines)
+ *outptr++ = '\n';
+
+ *save = 0;
+ *state = 0;
+
+ return outptr-out;
+}
+
+/*
+ performs an 'encode step', only encodes blocks of 3 characters to the
+ output at a time, saves left-over state in state and save (initialise to
+ 0 on first invocation).
+*/
+static size_t
+_evc_base64_encode_step(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save)
+{
+ register unsigned char *inptr, *outptr;
+
+ if (len<=0)
+ return 0;
+
+ inptr = in;
+ outptr = out;
+
+#if 0
+ d(printf("we have %d chars, and %d saved chars\n", len, ((char *)save)[0]));
+#endif
+
+ if (len + ((char *)save)[0] > 2) {
+ unsigned char *inend = in+len-2;
+ register int c1, c2, c3;
+ register int already;
+
+ already = *state;
+
+ switch (((char *)save)[0]) {
+ case 1: c1 = ((unsigned char *)save)[1]; goto skip1;
+ case 2: c1 = ((unsigned char *)save)[1];
+ c2 = ((unsigned char *)save)[2]; goto skip2;
+ }
+
+ /* yes, we jump into the loop, no i'm not going to change it, it's beautiful! */
+ while (inptr < inend) {
+ c1 = *inptr++;
+ skip1:
+ c2 = *inptr++;
+ skip2:
+ c3 = *inptr++;
+ *outptr++ = _evc_base64_alphabet[ c1 >> 2 ];
+ *outptr++ = _evc_base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 ) ];
+ *outptr++ = _evc_base64_alphabet[ ( (c2 &0x0f) << 2 ) | (c3 >> 6) ];
+ *outptr++ = _evc_base64_alphabet[ c3 & 0x3f ];
+ /* this is a bit ugly ... */
+ if (break_lines && (++already)>=19) {
+ *outptr++='\n';
+ already = 0;
+ }
+ }
+
+ ((char *)save)[0] = 0;
+ len = 2-(inptr-inend);
+ *state = already;
+ }
+
+#if 0
+ d(printf("state = %d, len = %d\n",
+ (int)((char *)save)[0],
+ len));
+#endif
+
+ if (len>0) {
+ register char *saveout;
+
+ /* points to the slot for the next char to save */
+ saveout = & (((char *)save)[1]) + ((char *)save)[0];
+
+ /* len can only be 0 1 or 2 */
+ switch(len) {
+ case 2: *saveout++ = *inptr++;
+ case 1: *saveout++ = *inptr++;
+ }
+ ((char *)save)[0]+=len;
+ }
+
+#if 0
+ d(printf("mode = %d\nc1 = %c\nc2 = %c\n",
+ (int)((char *)save)[0],
+ (int)((char *)save)[1],
+ (int)((char *)save)[2]));
+#endif
+
+ return outptr-out;
+}
+
+
+/**
+ * base64_decode_step: decode a chunk of base64 encoded data
+ * @in: input stream
+ * @len: max length of data to decode
+ * @out: output stream
+ * @state: holds the number of bits that are stored in @save
+ * @save: leftover bits that have not yet been decoded
+ *
+ * Decodes a chunk of base64 encoded data
+ **/
+static size_t
+_evc_base64_decode_step(unsigned char *in, size_t len, unsigned char *out, int *state, unsigned int *save)
+{
+ register unsigned char *inptr, *outptr;
+ unsigned char *inend, c;
+ register unsigned int v;
+ int i;
+
+ inend = in+len;
+ outptr = out;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
+ v=*save;
+ i=*state;
+ inptr = in;
+ while (inptr<inend) {
+ c = _evc_base64_rank[*inptr++];
+ if (c != 0xff) {
+ v = (v<<6) | c;
+ i++;
+ if (i==4) {
+ *outptr++ = v>>16;
+ *outptr++ = v>>8;
+ *outptr++ = v;
+ i=0;
+ }
+ }
+ }
+
+ *save = v;
+ *state = i;
+
+ /* quick scan back for '=' on the end somewhere */
+ /* fortunately we can drop 1 output char for each trailing = (upto 2) */
+ i=2;
+ while (inptr>in && i) {
+ inptr--;
+ if (_evc_base64_rank[*inptr] != 0xff) {
+ if (*inptr == '=' && outptr>out)
+ outptr--;
+ i--;
+ }
+ }
+
+ /* if i!= 0 then there is a truncation error! */
+ return outptr-out;
+}
+
+char *
+_evc_base64_encode_simple (const char *data, size_t len)
+{
+ unsigned char *out;
+ int state = 0, outlen;
+ unsigned int save = 0;
+
+ out = g_malloc (len * 4 / 3 + 5);
+ outlen = _evc_base64_encode_close ((unsigned char *)data, len, FALSE,
+ out, &state, &save);
+ out[outlen] = '\0';
+ return (char *)out;
+}
+
+size_t
+_evc_base64_decode_simple (char *data, size_t len)
+{
+ int state = 0;
+ unsigned int save = 0;
+
+ return _evc_base64_decode_step ((unsigned char *)data, len,
+ (unsigned char *)data, &state, &save);
+}
diff --git a/addressbook/backend/ebook/e-vcard.h b/addressbook/backend/ebook/e-vcard.h
index 69e0a3e10b..cedc2b4c70 100644
--- a/addressbook/backend/ebook/e-vcard.h
+++ b/addressbook/backend/ebook/e-vcard.h
@@ -26,18 +26,56 @@
#include <glib.h>
#include <glib-object.h>
-#define EVC_FN "FN"
-#define EVC_ORG "ORG"
-#define EVC_URL "URL"
-#define EVC_VERSION "VERSION"
-#define EVC_REV "REV"
-#define EVC_PRODID "PRODID"
-#define EVC_TYPE "TYPE"
-#define EVC_ADR "ADR"
-#define EVC_TEL "TEL"
-
-#define EVC_ENCODING "ENCODING"
+#define EVC_ADR "ADR"
+#define EVC_BDAY "BDAY"
+#define EVC_CALURI "CALURI"
+#define EVC_CATEGORIES "CATEGORIES"
+#define EVC_EMAIL "EMAIL"
+#define EVC_ENCODING "ENCODING"
+#define EVC_FBURL "FBURL"
+#define EVC_FN "FN"
+#define EVC_ICSCALENDAR "ICSCALENDAR" /* XXX should this be X-EVOLUTION-ICSCALENDAR? */
+#define EVC_LABEL "LABEL"
+#define EVC_LOGO "LOGO"
+#define EVC_MAILER "MAILER"
+#define EVC_NICKNAME "NICKNAME"
+#define EVC_N "N"
+#define EVC_NOTE "NOTE"
+#define EVC_ORG "ORG"
+#define EVC_PHOTO "PHOTO"
+#define EVC_PRODID "PRODID"
#define EVC_QUOTEDPRINTABLE "QUOTED-PRINTABLE"
+#define EVC_REV "REV"
+#define EVC_ROLE "ROLE"
+#define EVC_TEL "TEL"
+#define EVC_TITLE "TITLE"
+#define EVC_TYPE "TYPE"
+#define EVC_UID "UID"
+#define EVC_URL "URL"
+#define EVC_VALUE "VALUE"
+#define EVC_VERSION "VERSION"
+
+#define EVC_X_AIM "X-AIM"
+#define EVC_X_ANNIVERSARY "X-EVOLUTION-ANNIVERSARY"
+#define EVC_X_ASSISTANT "X-EVOLUTION-ASSISTANT"
+#define EVC_X_BIRTHDAY "X-EVOLUTION-BIRTHDAY"
+#define EVC_X_BLOG_URL "X-EVOLUTION-BLOG-URL"
+#define EVC_X_FILE_AS "X-EVOLUTION-FILE-AS"
+#define EVC_X_ICQ "X-ICQ"
+#define EVC_X_JABBER "X-JABBER"
+#define EVC_X_LIST_SHOW_ADDRESSES "X-EVOLUTION-LIST-SHOW_ADDRESSES"
+#define EVC_X_LIST "X-EVOLUTION-LIST"
+#define EVC_X_MANAGER "X-EVOLUTION-MANAGER"
+#define EVC_X_MSN "X-MSN"
+#define EVC_X_SPOUSE "X-EVOLUTION-SPOUSE"
+#define EVC_X_WANTS_HTML "X-MOZILLA-HTML"
+#define EVC_X_WANTS_HTML "X-MOZILLA-HTML"
+#define EVC_X_YAHOO "X-YAHOO"
+
+typedef enum {
+ EVC_FORMAT_VCARD_21,
+ EVC_FORMAT_VCARD_30
+} EVCardFormat;
#define E_TYPE_VCARD (e_vcard_get_type ())
#define E_VCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_VCARD, EVCard))
@@ -60,28 +98,46 @@ struct _EVCard {
struct _EVCardClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_ebook_reserved0) (void);
+ void (*_ebook_reserved1) (void);
+ void (*_ebook_reserved2) (void);
+ void (*_ebook_reserved3) (void);
+ void (*_ebook_reserved4) (void);
};
GType e_vcard_get_type (void);
+
+void e_vcard_construct (EVCard *evc, const char *str);
EVCard* e_vcard_new (void);
EVCard* e_vcard_new_from_string (const char *str);
-char* e_vcard_to_string (EVCard *evcard);
+
+char* e_vcard_to_string (EVCard *evc, EVCardFormat format);
+
/* mostly for debugging */
void e_vcard_dump_structure (EVCard *evc);
/* attributes */
-EVCardAttribute *e_vcard_attribute_new (const char *attr_group, const char *attr_name);
-void e_vcard_attribute_free (EVCardAttribute *attr);
-void e_vcard_add_attribute (EVCard *evcard, EVCardAttribute *attr);
-void e_vcard_add_attribute_with_value (EVCard *evcard, EVCardAttribute *attr, const char *value);
-void e_vcard_add_attribute_with_values (EVCard *evcard, EVCardAttribute *attr, ...);
-void e_vcard_attribute_add_value (EVCardAttribute *attr, const char *value);
-void e_vcard_attribute_add_values (EVCardAttribute *attr, ...);
+EVCardAttribute *e_vcard_attribute_new (const char *attr_group, const char *attr_name);
+void e_vcard_attribute_free (EVCardAttribute *attr);
+EVCardAttribute *e_vcard_attribute_copy (EVCardAttribute *attr);
+void e_vcard_remove_attributes (EVCard *evcard, const char *attr_group, const char *attr_name);
+void e_vcard_remove_attribute (EVCard *evcard, EVCardAttribute *attr);
+void e_vcard_add_attribute (EVCard *evcard, EVCardAttribute *attr);
+void e_vcard_add_attribute_with_value (EVCard *evcard, EVCardAttribute *attr, const char *value);
+void e_vcard_add_attribute_with_values (EVCard *evcard, EVCardAttribute *attr, ...);
+void e_vcard_attribute_add_value (EVCardAttribute *attr, const char *value);
+void e_vcard_attribute_add_value_decoded (EVCardAttribute *attr, const char *value, int len);
+void e_vcard_attribute_add_values (EVCardAttribute *attr, ...);
+void e_vcard_attribute_remove_values (EVCardAttribute *attr);
+void e_vcard_attribute_remove_params (EVCardAttribute *attr);
/* attribute parameters */
EVCardAttributeParam* e_vcard_attribute_param_new (const char *param_name);
void e_vcard_attribute_param_free (EVCardAttributeParam *param);
+EVCardAttributeParam* e_vcard_attribute_param_copy (EVCardAttributeParam *param);
void e_vcard_attribute_add_param (EVCardAttribute *attr, EVCardAttributeParam *param);
void e_vcard_attribute_add_param_with_value (EVCardAttribute *attr,
EVCardAttributeParam *param, const char *value);
@@ -92,17 +148,18 @@ void e_vcard_attribute_param_add_value (EVCardAttributePa
const char *value);
void e_vcard_attribute_param_add_values (EVCardAttributeParam *param,
...);
+void e_vcard_attribute_param_remove_values (EVCardAttributeParam *param);
/* EVCard* accessors. nothing returned from these functions should be
freed by the caller. */
GList* e_vcard_get_attributes (EVCard *evcard);
const char* e_vcard_attribute_get_group (EVCardAttribute *attr);
const char* e_vcard_attribute_get_name (EVCardAttribute *attr);
-GList* e_vcard_attribute_get_values (EVCardAttribute *attr);
+GList* e_vcard_attribute_get_values (EVCardAttribute *attr); /* GList elements are of type char* */
+GList* e_vcard_attribute_get_values_decoded (EVCardAttribute *attr); /* GList elements are of type GString* */
GList* e_vcard_attribute_get_params (EVCardAttribute *attr);
const char* e_vcard_attribute_param_get_name (EVCardAttributeParam *param);
GList* e_vcard_attribute_param_get_values (EVCardAttributeParam *param);
-
#endif /* _EVCARD_H */
diff --git a/addressbook/backend/ebook/test-client-list.c b/addressbook/backend/ebook/test-client-list.c
deleted file mode 100644
index 6fa3d6b094..0000000000
--- a/addressbook/backend/ebook/test-client-list.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-
-#include <glib.h>
-#include <bonobo/bonobo-i18n.h>
-#include <bonobo/bonobo-main.h>
-#include <libgnome/gnome-init.h>
-
-#include "e-book.h"
-
-static void
-init_bonobo (int *argc, char **argv)
-{
- if (bonobo_init (argc, argv) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-}
-
-static void
-get_cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure)
-{
- long length = e_card_cursor_get_length(cursor);
- long i;
-
- printf ("Length: %d\n", (int) length);
- for ( i = 0; i < length; i++ ) {
- ECard *card = e_card_cursor_get_nth(cursor, i);
- char *vcard = e_card_get_vcard_assume_utf8(card);
- printf("[%s]\n", vcard);
- g_free(vcard);
- g_object_unref(card);
- }
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- printf ("Book opened.\n");
- e_book_get_cursor(book, "", get_cursor_cb, NULL);
-}
-
-static gboolean
-ebook_create (gpointer data)
-{
- EBook *book;
-
- book = e_book_new ();
-
- e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL);
-
- return FALSE;
-}
-
-int
-main (int argc, char **argv)
-{
- gnome_program_init("test-client-list", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
-
- init_bonobo (&argc, argv);
-
- g_idle_add (ebook_create, NULL);
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/backend/ebook/test-client.c b/addressbook/backend/ebook/test-client.c
deleted file mode 100644
index 63461fb671..0000000000
--- a/addressbook/backend/ebook/test-client.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-#include <glib.h>
-#include <bonobo/bonobo-i18n.h>
-#include <bonobo/bonobo-main.h>
-#include <libgnome/gnome-init.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "e-book.h"
-#include "e-book-util.h"
-
-#define TEST_VCARD \
-"BEGIN:VCARD\r\n" \
-"FN:Nat\r\n" \
-"N:Friedman;Nat;D;Mr.\r\n" \
-"BDAY:1977-08-06\r\n" \
-"TEL;WORK:617 679 1984\r\n" \
-"TEL;CELL:123 456 7890\r\n" \
-"EMAIL;INTERNET:nat@nat.org\r\n" \
-"EMAIL;INTERNET:nat@ximian.com\r\n" \
-"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;\r\n" \
-"END:VCARD\r\n" \
-"\r\n"
-
-static CORBA_Environment ev;
-static char *cardstr;
-
-static void
-init_bonobo (int *argc, char **argv)
-{
- if (bonobo_init (argc, argv) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-}
-
-static void
-get_cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure)
-{
- long length = e_card_cursor_get_length(cursor);
- long i;
-
- /* we just added a card, so the length should be >1 */
- printf ("\n%s: %s(): Number of cards is %ld\n",
- __FILE__, G_GNUC_FUNCTION, length);
- if (length < 1)
- printf ("*** Why isn't this above zero?? ***\n\n");
-
- for ( i = 0; i < length; i++ ) {
- ECard *card = e_card_cursor_get_nth(cursor, i);
- char *vcard = e_card_get_vcard_assume_utf8(card);
- printf("Get all cards callback: [%s]\n", vcard);
- g_free(vcard);
- g_object_unref(card);
- }
-
- g_object_unref (book);
- exit(0);
-}
-
-static void
-get_card_cb (EBook *book, EBookStatus status, ECard *card, gpointer closure)
-{
- char *vcard;
-
- vcard = e_card_get_vcard_assume_utf8(card);
- printf ("Card added: [%s]\n", vcard);
- g_free(vcard);
-
- printf ("Getting cards..\n");
- e_book_get_cursor(book, "(contains \"x-evolution-any-field\" \"\")", get_cursor_cb, NULL);
- printf ("Done getting all cards.\n");
-}
-
-static void
-add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- GTimer *timer;
-
- printf ("Status: %d\n", status);
-
- printf ("Id: %s\n", id);
-
- timer = g_timer_new ();
- g_timer_start (timer);
- e_book_get_card (book, id, get_card_cb, closure);
- g_timer_stop (timer);
- printf ("%g\n", g_timer_elapsed (timer, NULL));
-}
-
-static void
-get_fields_cb (EBook *book, EBookStatus status, EList *fields, gpointer closure)
-{
- if (fields) {
- EIterator *iter = e_list_get_iterator (fields);
-
- printf ("Supported fields:\n");
-
- for (; e_iterator_is_valid (iter); e_iterator_next (iter)) {
- printf (" %s\n", (char*)e_iterator_get (iter));
- }
-
- g_object_unref(fields);
- }
- else {
- printf ("No supported fields?\n");
- }
-
- e_book_add_vcard(book, cardstr, add_card_cb, NULL);
-}
-
-
-static void
-auth_user_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- printf ("user authenticated\n");
- e_book_get_supported_fields (book, get_fields_cb, closure);
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- e_book_authenticate_user (book, "username", "password", "auth_method", auth_user_cb, NULL);
-}
-
-static gboolean
-ebook_create (gpointer data)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- G_GNUC_FUNCTION);
- return FALSE;
- }
-
-
- e_book_load_default_book (book, book_open_cb, NULL);
-
- return FALSE;
-}
-
-static char *
-read_file (char *name)
-{
- int len;
- char buff[65536];
- char line[1024];
- FILE *f;
-
- f = fopen (name, "r");
- if (f == NULL)
- g_error ("Unable to open %s!\n", name);
-
- len = 0;
- while (fgets (line, sizeof (line), f) != NULL) {
- strcpy (buff + len, line);
- len += strlen (line);
- }
-
- fclose (f);
-
- return g_strdup (buff);
-}
-
-
-int
-main (int argc, char **argv)
-{
-
- CORBA_exception_init (&ev);
-
- gnome_program_init("test-client", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
-
- init_bonobo (&argc, argv);
-
- cardstr = NULL;
- if (argc == 2)
- cardstr = read_file (argv [1]);
-
- if (cardstr == NULL)
- cardstr = TEST_VCARD;
-
- g_idle_add (ebook_create, NULL);
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/backend/ebook/tests/Makefile.am b/addressbook/backend/ebook/tests/Makefile.am
index f17f979485..444d692e22 100644
--- a/addressbook/backend/ebook/tests/Makefile.am
+++ b/addressbook/backend/ebook/tests/Makefile.am
@@ -1 +1 @@
-SUBDIRS=vcard \ No newline at end of file
+SUBDIRS=vcard ebook
diff --git a/addressbook/backend/ebook/tests/ebook/.cvsignore b/addressbook/backend/ebook/tests/ebook/.cvsignore
new file mode 100644
index 0000000000..8dbec11b01
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/.cvsignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+test-date
+test-ebook
+test-changes
+test-photo
+test-string
diff --git a/addressbook/backend/ebook/tests/ebook/Makefile.am b/addressbook/backend/ebook/tests/ebook/Makefile.am
new file mode 100644
index 0000000000..7147690482
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/Makefile.am
@@ -0,0 +1,12 @@
+
+TEST_LIBS=$(top_builddir)/addressbook/backend/ebook/libebook.la
+
+INCLUDES=-I$(srcdir)/../../.. @EVOLUTION_ADDRESSBOOK_CFLAGS@
+
+noinst_PROGRAMS= test-changes test-date test-ebook test-photo test-string
+
+test_date_LDFLAGS=$(TEST_LIBS)
+test_ebook_LDFLAGS=$(TEST_LIBS)
+test_changes_LDFLAGS=$(TEST_LIBS)
+test_photo_LDFLAGS=$(TEST_LIBS)
+test_string_LDFLAGS=$(TEST_LIBS)
diff --git a/addressbook/backend/ebook/tests/ebook/test-changes.c b/addressbook/backend/ebook/tests/ebook/test-changes.c
new file mode 100644
index 0000000000..0c91f30cf4
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/test-changes.c
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include "ebook/e-book.h"
+#include <libgnome/gnome-init.h>
+#include <bonobo/bonobo-main.h>
+#include <stdlib.h>
+
+#define NEW_VCARD "BEGIN:VCARD\n\
+X-EVOLUTION-FILE-AS:Toshok, Chris\n\
+FN:Chris Toshok\n\
+EMAIL;INTERNET:toshok@ximian.com\n\
+ORG:Ximian, Inc.;\n\
+END:VCARD"
+
+static char file_template[]="file:///tmp/change-test-XXXXXX";
+
+int
+main (int argc, char **argv)
+{
+ EBook *book;
+ gboolean status;
+ EContact *contact;
+ GList *changes;
+ GError *error = NULL;
+ EBookChange *change;
+
+ gnome_program_init("test-changes", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
+
+ if (bonobo_init (&argc, argv) == FALSE)
+ g_error ("Could not initialize Bonobo");
+
+ mktemp (file_template);
+
+ /* create a temp addressbook in /tmp */
+ book = e_book_new ();
+
+ printf ("loading addressbook\n");
+ if (!e_book_load_uri (book, file_template, FALSE, &error)) {
+ printf ("failed to open addressbook: `%s': %s\n", file_template, error->message);
+ exit(0);
+ }
+
+ /* get an initial change set */
+ if (!e_book_get_changes (book, "changeidtest", &changes, &error)) {
+ printf ("failed to get changes: %s\n", error->message);
+ exit(0);
+ }
+
+ /* make a change to the book */
+ contact = e_contact_new_from_vcard (NEW_VCARD);
+ if (!e_book_add_contact (book, contact, &error)) {
+ printf ("failed to add new contact: %s\n", error->message);
+ exit(0);
+ }
+
+ /* get another change set */
+ if (!e_book_get_changes (book, "changeidtest", &changes, &error)) {
+ printf ("failed to get second set of changes: %s\n", error->message);
+ exit(0);
+ }
+
+ /* make sure that 1 change has occurred */
+ if (g_list_length (changes) != 1) {
+ printf ("got back %d changes, was expecting 1\n", g_list_length (changes));
+ exit(0);
+ }
+
+ change = changes->data;
+ if (change->change_type != E_BOOK_CHANGE_CARD_ADDED) {
+ printf ("was expecting a CARD_ADDED change, but didn't get it.\n");
+ exit(0);
+ }
+
+ printf ("got changed vcard back: %s\n", change->vcard);
+
+ e_book_free_change_list (changes);
+
+
+ if (!e_book_remove (book, &error)) {
+ printf ("failed to remove book; %s\n", error->message);
+ exit(0);
+ }
+
+ g_object_unref (book);
+
+ bonobo_main_quit();
+
+ return 0;
+}
diff --git a/addressbook/backend/ebook/tests/ebook/test-date.c b/addressbook/backend/ebook/tests/ebook/test-date.c
new file mode 100644
index 0000000000..afe37cf224
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/test-date.c
@@ -0,0 +1,36 @@
+
+#include "ebook/e-book.h"
+#include <libgnome/gnome-init.h>
+#include <bonobo/bonobo-main.h>
+#include <stdlib.h>
+
+int
+main (int argc, char **argv)
+{
+ EContact *contact;
+ EContactDate date, *dp;
+
+ gnome_program_init("test-string", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
+
+ if (bonobo_init (&argc, argv) == FALSE)
+ g_error ("Could not initialize Bonobo");
+
+ contact = e_contact_new ();
+
+ date.year = 1999;
+ date.month = 3;
+ date.day = 3;
+
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, &date);
+
+ printf ("vcard = \n%s\n", e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
+
+ dp = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+
+ if (dp->year != date.year
+ || dp->month != date.month
+ || dp->day != date.day)
+ printf ("failed\n");
+ else
+ printf ("passed\n");
+}
diff --git a/addressbook/backend/ebook/tests/ebook/test-ebook.c b/addressbook/backend/ebook/tests/ebook/test-ebook.c
new file mode 100644
index 0000000000..d78d9f3b6a
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/test-ebook.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include "ebook/e-book.h"
+#include <libgnome/gnome-init.h>
+#include <bonobo/bonobo-main.h>
+#include <stdlib.h>
+
+static void
+print_email (EContact *contact)
+{
+ char *file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+ GList *emails, *e;
+
+ printf ("Contact: %s\n", file_as);
+ printf ("Email addresses:\n");
+ emails = e_contact_get (contact, E_CONTACT_EMAIL);
+ for (e = emails; e; e = e->next) {
+ EVCardAttribute *attr = e->data;
+ GList *values = e_vcard_attribute_get_values (attr);
+ printf ("\t%s\n", values && values->data ? (char*)values->data : "");
+ e_vcard_attribute_free (attr);
+ }
+ g_list_free (emails);
+
+ g_free (file_as);
+
+ printf ("\n");
+}
+
+static void
+print_all_emails (EBook *book)
+{
+ EBookQuery *query;
+ gboolean status;
+ GList *cards, *c;
+
+ query = e_book_query_field_exists (E_CONTACT_FULL_NAME);
+
+ status = e_book_get_contacts (book, query, &cards, NULL);
+
+ e_book_query_unref (query);
+
+ if (status == FALSE) {
+ printf ("error %d getting card list\n", status);
+ exit(0);
+ }
+
+ for (c = cards; c; c = c->next) {
+ EContact *contact = E_CONTACT (c->data);
+
+ print_email (contact);
+
+ g_object_unref (contact);
+ }
+ g_list_free (cards);
+}
+
+static void
+print_one_email (EBook *book)
+{
+ EContact *contact;
+ GError *error = NULL;
+
+ if (!e_book_get_contact (book, "pas-id-0002023", &contact, &error)) {
+ printf ("error %d getting card: %s\n", error->code, error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ print_email (contact);
+
+ g_object_unref (contact);
+}
+
+int
+main (int argc, char **argv)
+{
+ EBook *book;
+ gboolean status;
+
+ gnome_program_init("test-ebook", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
+
+ if (bonobo_init (&argc, argv) == FALSE)
+ g_error ("Could not initialize Bonobo");
+
+ /*
+ ** the actual ebook foo
+ */
+
+ book = e_book_new ();
+
+ printf ("loading addressbook\n");
+ status = e_book_load_local_addressbook (book, NULL);
+ if (status == FALSE) {
+ printf ("failed to open local addressbook\n");
+ exit(0);
+ }
+
+ printf ("printing one contact\n");
+ print_one_email (book);
+
+ printf ("printing all contacts\n");
+ print_all_emails (book);
+
+ g_object_unref (book);
+
+ bonobo_main_quit();
+
+ return 0;
+}
diff --git a/addressbook/backend/ebook/tests/ebook/test-photo.c b/addressbook/backend/ebook/tests/ebook/test-photo.c
new file mode 100644
index 0000000000..cbd6817b37
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/test-photo.c
@@ -0,0 +1,59 @@
+
+#include "ebook/e-book.h"
+#include <libgnome/gnome-init.h>
+#include <bonobo/bonobo-main.h>
+#include <stdlib.h>
+
+const char *photo_data = "/9j/4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRo\
+IFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLC\
+McHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIy\
+MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAMgAyAwEiAAIRAQMRAf\
+/EABsAAQACAwEBAAAAAAAAAAAAAAAHCAQFBgID/8QAMBAAAgEDAQYEBQQDAAAAAAAAAQIDAAQR\
+BQYSEyExQQdhcYEiI0JRkRQVMqFiguH/xAAaAQADAQEBAQAAAAAAAAAAAAAABAUCBgED/8QAIx\
+EAAgICAQQCAwAAAAAAAAAAAAECAwQRQRITITEUYQUiUf/aAAwDAQACEQMRAD8An+sHUtWtNKjV\
+rmQ7754cajLvjrgfbzPIdzWdVfds9pJb3XdQkMrcFZGj+HqY0bdVV9Tz/wBia+N9vbjvkaxMb5\
+E9N6SJB1HxLEEjJaWsUjD6QzSMPXdGB7E1zV74t63HINy1s4F7CWCTn77wrA0TY86jY3N1qsUk\
+6wxBxBDvYjLHkoUH4j3JP/a0V3s1CvF/QM9tKpw0THeU+TLkj8VLnmzT8y0n9FujBx5bioba/r\
+ZLWx3iPZ7RzLp95GtnqRGVTezHNjruH7/4n+67iqpq7Qi3uYWMMsNynfnE6sM8/Lr6VamFi0KM\
+epUE1Sx7XZHbI+fjxos1H0z3SlKYEjzISI2I64OKqsyu8sck2QYrmPjBvpIYg598Vauoh8VtlY\
+7JW2isoBwpPl6hGByZTyD+o6E+h7UtlVOcPHA/+PyI1Wal6Zp7vaC/06wnTTLtEeUDiKwzu4H8\
+vI9AM9Tiuctkng1Nnk1G5cOoYifB4nI/jB7VjWuoT21qPmwXUCHKlphHKvqG5N6g0/cLi/Rg88\
+FhbkbxlaUSu3kqpnn6kDzqGqbNdPB0XyK4/svZr9RVntL50GePdcKEDqzhVBx7sKtPpayppNos\
+xzKIlDHzxUFeG2zo2n2kivWhK6PpHwwoTnfk65J7kZyT9z5VYADAwKuYtfRA5zPv7tnjgUpSmR\
+EV8bq1hvbWW1uY1khlUo6MMhgeor7UoAje18FtmLe9eeQT3EXPcglkJRPbv71EWu7Dajp2o3MG\
+mlRCkjKQ30jPUe1WlrlNW0RptTleNB84DnjkD0P9VlxT4Nqck9pmn8JuFp2zo0cgCWFi2e7555\
+/NSHXLadso2m3sU0NxlV65HM+VdTW3rgwvsUpSvAFKUoAUxSlAClKUAKUpQB//2Q==";
+
+
+int
+main (int argc, char **argv)
+{
+ EContact *contact;
+ EContactPhoto *photo, *new_photo;
+
+ gnome_program_init("test-photo", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
+
+ if (bonobo_init (&argc, argv) == FALSE)
+ g_error ("Could not initialize Bonobo");
+
+ contact = e_contact_new ();
+
+ photo = g_new (EContactPhoto, 1);
+ photo->data = g_strdup (photo_data);
+ photo->length = _evc_base64_decode_simple (photo->data, strlen (photo_data));
+
+ /* set the photo */
+ e_contact_set (contact, E_CONTACT_PHOTO, photo);
+
+ /* then get the photo */
+ new_photo = e_contact_get (contact, E_CONTACT_PHOTO);
+
+ /* and compare */
+ if (new_photo->length != photo->length)
+ g_error ("photo lengths differ");
+
+ if (memcmp (new_photo->data, photo->data, photo->length))
+ g_error ("photo data differs");
+
+ printf ("photo test passed\n");
+}
diff --git a/addressbook/backend/ebook/tests/ebook/test-string.c b/addressbook/backend/ebook/tests/ebook/test-string.c
new file mode 100644
index 0000000000..b7cdbb3720
--- /dev/null
+++ b/addressbook/backend/ebook/tests/ebook/test-string.c
@@ -0,0 +1,27 @@
+
+#include "ebook/e-book.h"
+#include <libgnome/gnome-init.h>
+#include <bonobo/bonobo-main.h>
+#include <stdlib.h>
+
+#define TEST_ID "test-uid"
+
+int
+main (int argc, char **argv)
+{
+ EContact *contact;
+
+ gnome_program_init("test-string", "0.0", LIBGNOME_MODULE, argc, argv, NULL);
+
+ if (bonobo_init (&argc, argv) == FALSE)
+ g_error ("Could not initialize Bonobo");
+
+ contact = e_contact_new ();
+
+ e_contact_set (contact, E_CONTACT_UID, TEST_ID);
+
+ if (!strcmp (e_contact_get_const (contact, E_CONTACT_UID), TEST_ID))
+ printf ("passed\n");
+ else
+ printf ("failed\n");
+}
diff --git a/addressbook/backend/ebook/tests/vcard/Makefile.am b/addressbook/backend/ebook/tests/vcard/Makefile.am
index ae16780095..7e57329e1d 100644
--- a/addressbook/backend/ebook/tests/vcard/Makefile.am
+++ b/addressbook/backend/ebook/tests/vcard/Makefile.am
@@ -1,6 +1,8 @@
-CFLAGS=-I$(srcdir)/../.. `pkg-config --cflags gobject-2.0`
+TEST_LIBS=$(top_builddir)/addressbook/backend/ebook/libebook.la
+
+INCLUDES=-I$(srcdir)/../../.. @EVOLUTION_ADDRESSBOOK_CFLAGS@
noinst_PROGRAMS=dump-vcard
-dump_vcard_LDFLAGS=$(top_builddir)/addressbook/backend/ebook/libevcard.la `pkg-config --libs gobject-2.0`
+dump_vcard_LDFLAGS=$(TEST_LIBS)
diff --git a/addressbook/backend/ebook/tests/vcard/dump-vcard.c b/addressbook/backend/ebook/tests/vcard/dump-vcard.c
index 52dbf8a957..907a00efa7 100644
--- a/addressbook/backend/ebook/tests/vcard/dump-vcard.c
+++ b/addressbook/backend/ebook/tests/vcard/dump-vcard.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#include <stdio.h>
-#include "e-vcard.h"
+#include "ebook/e-vcard.h"
FILE *fp;
diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl
index c9ce728a15..1ad3a62dd9 100644
--- a/addressbook/backend/idl/addressbook.idl
+++ b/addressbook/backend/idl/addressbook.idl
@@ -12,98 +12,120 @@
module GNOME {
module Evolution {
module Addressbook {
- typedef string CardId;
+ typedef string ContactId;
typedef string VCard;
typedef sequence<VCard> VCardList;
- typedef sequence<CardId> CardIdList;
+ typedef sequence<ContactId> ContactIdList;
typedef sequence<string> stringlist;
- interface CardCursor : Bonobo::Unknown {
- long count ();
- string getNth (in long n);
+ enum BookChangeType {
+ ContactAdded,
+ ContactModified,
+ ContactDeleted
+ };
+
+ union BookChangeItem switch (BookChangeType) {
+ case ContactAdded:
+ VCard add_vcard;
+ case ContactModified:
+ VCard mod_vcard;
+ case ContactDeleted:
+ ContactId del_id;
+ };
+
+ typedef sequence<BookChangeItem> BookChangeList;
+
+ enum CallStatus {
+ Success,
+ RepositoryOffline,
+ PermissionDenied,
+ ContactNotFound,
+ ContactIdAlreadyExists,
+ AuthenticationFailed,
+ AuthenticationRequired,
+ UnsupportedField,
+ UnsupportedAuthenticationMethod,
+ TLSNotAvailable,
+ NoSuchBook,
+ BookRemoved,
+
+ /* These can be returned for successful searches, but
+ indicate the result set was truncated */
+ SearchSizeLimitExceeded,
+ SearchTimeLimitExceeded,
+
+ InvalidQuery,
+ QueryRefused,
+
+ CouldNotCancel,
+
+ OtherError
};
/*
* A book view is a live view of a book. It's either a view
- * of all the cards in the book or a view of a query. When
- * created, it will get a series of signal_card_added calls
+ * of all the contacts in the book or a view of a query. When
+ * created, it will get a series of notifyContactsAdded calls
* for all objects in the initial set. After that, it will
* get added, removed, or changed signals whenever the book
- * changes (if it affects the set of viewed cards.)
+ * changes (if it affects the set of viewed contacts.)
*/
interface BookViewListener : Bonobo::Unknown {
- enum CallStatus {
- Success,
- /* These are still successful searches, but
- the result set was truncated */
- SearchSizeLimitExceeded,
- SearchTimeLimitExceeded,
-
- /* These are failures */
- InvalidQuery,
- QueryRefused,
- OtherError
- };
- void notifyCardAdded (in VCardList cards);
- void notifyCardsRemoved (in CardIdList ids);
- void notifyCardChanged (in VCardList cards);
- void notifySequenceComplete (in CallStatus status);
- void notifyStatusMessage (in string message);
+ oneway void notifyContactsAdded (in VCardList vcards);
+ oneway void notifyContactsRemoved (in ContactIdList ids);
+ oneway void notifyContactsChanged (in VCardList vcards);
+ oneway void notifySequenceComplete (in CallStatus status);
+ oneway void notifyProgress (in string message, in short percent);
};
interface BookView : Bonobo::Unknown {
+ oneway void start ();
};
interface Book : Bonobo::Unknown {
/*
- * Fetching cards in the addresbook.
+ * Opening/creating addressbooks.
*/
- void getVCard (in CardId id);
+ oneway void open (in boolean only_if_exists);
- void authenticateUser (in string user, in string passwd,
- in string authMethod);
+ /*
+ * Removing addressbooks.
+ */
+ oneway void remove ();
/*
- * Adding and deleting cards in the book.
+ * Fetching contacts in the addresbook.
*/
- void addCard (in VCard vcard);
- void removeCards (in CardIdList Id);
-
+ oneway void getContact (in ContactId id);
+
+ oneway void authenticateUser (in string user, in string passwd,
+ in string authMethod);
+
/*
- * Modifying cards in the addressbook.
+ * Adding and deleting contacts in the book.
*/
- void modifyCard (in VCard vcard);
-
+ oneway void addContact (in VCard vcard);
+ oneway void removeContacts (in ContactIdList Id);
+
/*
- * This function returns a cursor to the book
- * listener. This is for people who want a snapshot
- * of the addressbook.
+ * Modifying contacts in the addressbook.
*/
- void getCursor (in string query);
+ oneway void modifyContact (in VCard vcard);
/*
* These two functions return a book view to the book
* listener. This is for people who want a live view
* of the addressbook.
*/
- void getBookView (in BookViewListener listener, in string query);
+ oneway void getBookView (in BookViewListener listener, in string query,
+ in stringlist requested_fields, in long max_results);
- void getChanges (in BookViewListener listener, in string change_id);
+ oneway void getChanges (in string change_id);
- /*
- * This function returns a book view that is identical
- * to a normal book view, except in one way - The only
- * values reflected in the cards that are transfered
- * back are: File As, family name, given name, email
- * addresses, and nickname. It is intended for use in
- * completion searches.
- */
- void getCompletionView (in BookViewListener listener, in string query);
-
- void checkConnection ();
+ oneway void getContactList (in string query);
- void getSupportedFields ();
+ oneway void getSupportedFields ();
/*
* This function returns a list of strings
@@ -127,86 +149,40 @@ module Addressbook {
* as it will be passed unchanged to the backend auth
* function (eg. ldap_sasl_bind)
*/
- void getSupportedAuthMethods ();
+ oneway void getSupportedAuthMethods ();
string getStaticCapabilities ();
string getName ();
+
+ /* cancels the currently running operation, whatever
+ it is. */
+ CallStatus cancelOperation ();
};
interface BookListener : Bonobo::Unknown {
- enum CallStatus {
- Success,
- RepositoryOffline,
- PermissionDenied,
- CardNotFound,
- CardIdAlreadyExists,
- ProtocolNotSupported,
- AuthenticationFailed,
- AuthenticationRequired,
- UnsupportedField,
- UnsupportedAuthenticationMethod,
- TLSNotAvailable,
- NoSuchBook,
-
- OtherError
- };
-
- void notifyCardCreated (in CallStatus status, in CardId Id);
-
- void notifyCardsRemoved (in CallStatus status);
-
- void notifyCardModified (in CallStatus status);
-
- void notifyOpenBookProgress (in string status_message, in short percent);
-
- void notifyBookOpened (in CallStatus status, in Book book);
-
- void notifyCardRequested (in CallStatus status, in VCard card);
-
- void notifyCursorRequested (in CallStatus status, in CardCursor cursor);
-
- void notifyViewRequested (in CallStatus status, in BookView view);
-
- void notifyChangesRequested (in CallStatus status, in BookView view);
-
- void notifyAuthenticationResult (in CallStatus status);
-
- void notifySupportedFields (in CallStatus status, in stringlist fields);
-
- void notifySupportedAuthMethods (in CallStatus status, in stringlist fields);
-
- /**
- * notifyConnectionStatus:
- *
- * Used to report changes in the connection to the
- * contact repository. This is often a response to a
- * call to check_connection() on the Book, but wombat
- * is free to report the connection status without
- * being asked.
- */
- void notifyConnectionStatus (in boolean connected);
-
- /**
- * notifyWritable:
- *
- * Used to report whether or not a backend can write
- * to a given addressbook. All books default to
- * read-only, so unless you receive a notification
- * saying otherwise, treat the book as read-only. It
- * is presumed that this notification will be sent
- * early (just after a connection is opened, usually),
- * but it may also be sent later, if/when the backend
- * notices a change.
- */
- void notifyWritable (in boolean writable);
+ oneway void notifyContactCreated (in CallStatus status, in ContactId Id);
+ oneway void notifyContactsRemoved (in CallStatus status);
+ oneway void notifyContactModified (in CallStatus status);
+ oneway void notifyProgress (in string status_message, in short precent);
+ oneway void notifyBookOpened (in CallStatus status);
+ oneway void notifyBookRemoved (in CallStatus status);
+ oneway void notifyViewRequested (in CallStatus status, in BookView view);
+ oneway void notifyChangesRequested (in CallStatus status, in BookChangeList changes);
+ oneway void notifyContactRequested (in CallStatus status, in VCard vcard);
+ oneway void notifyContactListRequested (in CallStatus status, in stringlist contacts);
+ oneway void notifySupportedFields (in CallStatus status, in stringlist fields);
+ oneway void notifyAuthenticationResult (in CallStatus status);
+ oneway void notifySupportedAuthMethods (in CallStatus status, in stringlist auth_methods);
+
+ oneway void notifyWritable (in boolean writable);
};
interface BookFactory : Bonobo::Unknown {
exception ProtocolNotSupported {};
- void openBook (in string uri, in BookListener listener)
+ Book getBook (in string uri, in BookListener listener)
raises (ProtocolNotSupported);
};
};
diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am
index c618050ca2..b602a21512 100644
--- a/addressbook/backend/pas/Makefile.am
+++ b/addressbook/backend/pas/Makefile.am
@@ -42,7 +42,7 @@ ldapschemadir = $(privdatadir)
ldapschema_DATA= $(LDAP_SCHEMA)
privlib_LIBRARIES = libpas.a
-noinst_LIBRARIES = libpasfile.a $(LDAP_BACKEND)
+noinst_LIBRARIES = libpasfile.a libpasvcf.a $(LDAP_BACKEND)
pasincludedir = $(privincludedir)/pas
@@ -54,7 +54,8 @@ pasinclude_HEADERS = \
pas-backend-card-sexp.h \
pas-backend.h \
pas-backend-summary.h \
- pas-card-cursor.h
+ pas-backend-sync.h \
+ pas-types.h
libpas_a_SOURCES = \
$(pasinclude_HEADERS) \
@@ -66,13 +67,18 @@ libpas_a_SOURCES = \
pas-backend-file.c \
pas-backend.c \
pas-backend-summary.c \
- pas-card-cursor.c \
- pas-marshal.c
+ pas-backend-sync.c \
+ pas-marshal.c \
+ ximian-vcard.h
libpasfile_a_SOURCES = \
pas-backend-file.c \
pas-backend-file.h
+libpasvcf_a_SOURCES = \
+ pas-backend-vcf.c \
+ pas-backend-vcf.h
+
if ENABLE_LDAP
libpasldap_a_SOURCES = \
$(LDAP_BACKEND_FILES)
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c
index e7b5d8a87d..1ccb4f2433 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.c
+++ b/addressbook/backend/pas/pas-backend-card-sexp.c
@@ -22,7 +22,6 @@
#include <string.h>
#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
#include <gal/widgets/e-unicode.h>
static GObjectClass *parent_class;
@@ -35,17 +34,17 @@ struct _PASBackendCardSExpPrivate {
};
struct _SearchContext {
- ECardSimple *card;
+ EContact *contact;
};
static gboolean
-compare_email (ECardSimple *card, const char *str,
+compare_email (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
int i;
- for (i = E_CARD_SIMPLE_EMAIL_ID_EMAIL; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) {
- const char *email = e_card_simple_get_email (card, i);
+ for (i = E_CONTACT_EMAIL_1; i <= E_CONTACT_EMAIL_3; i ++) {
+ const char *email = e_contact_get_const (contact, i);
if (email && compare(email, str))
return TRUE;
@@ -55,32 +54,36 @@ compare_email (ECardSimple *card, const char *str,
}
static gboolean
-compare_phone (ECardSimple *card, const char *str,
+compare_phone (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
int i;
+ gboolean rv = FALSE;
- for (i = E_CARD_SIMPLE_PHONE_ID_ASSISTANT; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- const ECardPhone *phone = e_card_simple_get_phone (card, i);
+ for (i = E_CONTACT_FIRST_PHONE_ID; i <= E_CONTACT_LAST_PHONE_ID; i ++) {
+ char *phone = e_contact_get (contact, i);
- if (phone && compare(phone->number, str))
- return TRUE;
+ rv = phone && compare(phone, str);
+ g_free (phone);
+
+ if (rv)
+ break;
}
- return FALSE;
+ return rv;
}
static gboolean
-compare_name (ECardSimple *card, const char *str,
+compare_name (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
const char *name;
- name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FULL_NAME);
+ name = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
if (name && compare (name, str))
return TRUE;
- name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FAMILY_NAME);
+ name = e_contact_get_const (contact, E_CONTACT_FAMILY_NAME);
if (name && compare (name, str))
return TRUE;
@@ -88,7 +91,7 @@ compare_name (ECardSimple *card, const char *str,
}
static gboolean
-compare_address (ECardSimple *card, const char *str,
+compare_address (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
g_warning("address searching not implemented\n");
@@ -96,23 +99,17 @@ compare_address (ECardSimple *card, const char *str,
}
static gboolean
-compare_category (ECardSimple *card, const char *str,
+compare_category (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
- EList *categories;
- EIterator *iterator;
- ECard *ecard;
+ GList *categories;
+ GList *iterator;
gboolean ret_val = FALSE;
- g_object_get (card,
- "card", &ecard,
- NULL);
- g_object_get (ecard,
- "category_list", &categories,
- NULL);
+ categories = e_contact_get (contact, E_CONTACT_CATEGORY_LIST);
- for (iterator = e_list_get_iterator(categories); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- const char *category = e_iterator_get (iterator);
+ for (iterator = categories; iterator; iterator = iterator->next) {
+ const char *category = iterator->data;
if (compare(category, str)) {
ret_val = TRUE;
@@ -120,83 +117,45 @@ compare_category (ECardSimple *card, const char *str,
}
}
- g_object_unref (iterator);
- e_card_free_empty_lists (ecard);
- g_object_unref (categories);
- g_object_unref (ecard);
- return ret_val;
-}
-
-static gboolean
-compare_arbitrary (ECardSimple *card, const char *str,
- char *(*compare)(const char*, const char*))
-{
- EList *list;
- EIterator *iterator;
- ECard *ecard;
- gboolean ret_val = FALSE;
-
- g_object_get (card,
- "card", &ecard,
- NULL);
- g_object_get (ecard,
- "arbitrary", &list,
- NULL);
-
- for (iterator = e_list_get_iterator(list); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get (iterator);
+ g_list_foreach (categories, (GFunc)g_free, NULL);
+ g_list_free (categories);
- if (compare(arbitrary->key, str)) {
- ret_val = TRUE;
- break;
- }
- }
-
- g_object_unref (iterator);
- e_card_free_empty_lists (ecard);
- g_object_unref (list);
- g_object_unref (ecard);
return ret_val;
}
static struct prop_info {
- ECardSimpleField field_id;
+ EContactField field_id;
const char *query_prop;
- const char *ecard_prop;
#define PROP_TYPE_NORMAL 0x01
#define PROP_TYPE_LIST 0x02
-#define PROP_TYPE_LISTITEM 0x03
-#define PROP_TYPE_ID 0x04
int prop_type;
- gboolean (*list_compare)(ECardSimple *ecard, const char *str,
+ gboolean (*list_compare)(EContact *contact, const char *str,
char *(*compare)(const char*, const char*));
} prop_info_table[] = {
-#define NORMAL_PROP(f,q,e) {f, q, e, PROP_TYPE_NORMAL, NULL}
-#define ID_PROP {0, "id", NULL, PROP_TYPE_ID, NULL}
-#define LIST_PROP(q,e,c) {0, q, e, PROP_TYPE_LIST, c}
-
- /* query prop, ecard prop, type, list compare function */
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "file_as" ),
- LIST_PROP ( "full_name", "full_name", compare_name), /* not really a list, but we need to compare both full and surname */
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_URL, "url", "url" ),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG, "org", "org"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "org_unit"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_OFFICE, "office", "office"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_TITLE, "title", "title"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ROLE, "role", "role"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MANAGER, "manager", "manager"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistant"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "nickname"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouse" ),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NOTE, "note", "note"),
- ID_PROP,
- LIST_PROP ( "email", "email", compare_email ),
- LIST_PROP ( "phone", "phone", compare_phone ),
- LIST_PROP ( "address", "address", compare_address ),
- LIST_PROP ( "category", "category", compare_category ),
- LIST_PROP ( "arbitrary", "arbitrary", compare_arbitrary )
+#define NORMAL_PROP(f,q) {f, q, PROP_TYPE_NORMAL, NULL}
+#define LIST_PROP(q,c) {0, q, PROP_TYPE_LIST, c}
+
+ /* query prop, type, list compare function */
+ NORMAL_PROP ( E_CONTACT_FILE_AS, "file_as" ),
+ LIST_PROP ( "full_name", compare_name), /* not really a list, but we need to compare both full and surname */
+ NORMAL_PROP ( E_CONTACT_HOMEPAGE_URL, "url"),
+ NORMAL_PROP ( E_CONTACT_MAILER, "mailer"),
+ NORMAL_PROP ( E_CONTACT_ORG, "org"),
+ NORMAL_PROP ( E_CONTACT_ORG_UNIT, "org_unit"),
+ NORMAL_PROP ( E_CONTACT_OFFICE, "office"),
+ NORMAL_PROP ( E_CONTACT_TITLE, "title"),
+ NORMAL_PROP ( E_CONTACT_ROLE, "role"),
+ NORMAL_PROP ( E_CONTACT_MANAGER, "manager"),
+ NORMAL_PROP ( E_CONTACT_ASSISTANT, "assistant"),
+ NORMAL_PROP ( E_CONTACT_NICKNAME, "nickname"),
+ NORMAL_PROP ( E_CONTACT_SPOUSE, "spouse" ),
+ NORMAL_PROP ( E_CONTACT_NOTE, "note"),
+ NORMAL_PROP ( E_CONTACT_UID, "id"),
+ LIST_PROP ( "email", compare_email ),
+ LIST_PROP ( "phone", compare_phone ),
+ LIST_PROP ( "address", compare_address ),
+ LIST_PROP ( "category", compare_category ),
};
static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]);
@@ -225,28 +184,10 @@ entry_compare(SearchContext *ctx, struct _ESExp *f,
info = &prop_info_table[i];
if (info->prop_type == PROP_TYPE_NORMAL) {
- char *prop = NULL;
- /* searches where the query's property
- maps directly to an ecard property */
-
- prop = e_card_simple_get (ctx->card, info->field_id);
-
- if (prop && compare(prop, argv[1]->value.string)) {
- truth = TRUE;
- }
- if ((!prop) && compare("", argv[1]->value.string)) {
- truth = TRUE;
- }
- g_free (prop);
- } else if (info->prop_type == PROP_TYPE_LIST) {
- /* the special searches that match any of the list elements */
- truth = info->list_compare (ctx->card, argv[1]->value.string, compare);
- } else if (info->prop_type == PROP_TYPE_ID) {
const char *prop = NULL;
- /* searches where the query's property
- maps directly to an ecard property */
+ /* straight string property matches */
- prop = e_card_get_id (ctx->card->card);
+ prop = e_contact_get_const (ctx->contact, info->field_id);
if (prop && compare(prop, argv[1]->value.string)) {
truth = TRUE;
@@ -255,6 +196,10 @@ entry_compare(SearchContext *ctx, struct _ESExp *f,
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, compare);
+ }
/* if we're looking at all fields and find a match,
or if we're just looking at this one field,
@@ -335,6 +280,51 @@ func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *da
return entry_compare (ctx, f, argc, argv, beginswith_helper);
}
+static ESExpResult *
+func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ SearchContext *ctx = data;
+ ESExpResult *r;
+ int truth = FALSE;
+
+ if (argc == 1
+ && argv[0]->type == ESEXP_RES_STRING) {
+ char *propname;
+ struct prop_info *info = NULL;
+ int i;
+
+ propname = argv[0]->value.string;
+
+ for (i = 0; i < num_prop_infos; i ++) {
+ if (!strcmp (prop_info_table[i].query_prop, propname)) {
+ info = &prop_info_table[i];
+
+ if (info->prop_type == PROP_TYPE_NORMAL) {
+ const char *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, "", (char *(*)(const char*, const char*)) e_utf8_strstrcase);
+ }
+
+ break;
+ }
+ }
+
+ }
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = truth;
+
+ return r;
+}
+
/* 'builtin' functions */
static struct {
char *name;
@@ -346,25 +336,27 @@ static struct {
{ "is", func_is, 0 },
{ "beginswith", func_beginswith, 0 },
{ "endswith", func_endswith, 0 },
+ { "exists", func_exists, 0 },
};
gboolean
-pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard)
+pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact)
{
ESExpResult *r;
gboolean retval;
- 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)
+ if (!contact) {
+ g_warning ("null EContact passed to pas_backend_card_sexp_match_contact");
return FALSE;
+ }
+
+ sexp->priv->search_context->contact = g_object_ref (contact);
r = e_sexp_eval(sexp->priv->search_sexp);
retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool);
- g_object_unref(sexp->priv->search_context->card);
+ g_object_unref(sexp->priv->search_context->contact);
e_sexp_result_free(sexp->priv->search_sexp, r);
@@ -374,14 +366,14 @@ pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard)
gboolean
pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
{
- ECard *card;
+ EContact *contact;
gboolean retval;
- card = e_card_new ((char*)vcard);
+ contact = e_contact_new_from_vcard (vcard);
- retval = pas_backend_card_sexp_match_ecard (sexp, card);
+ retval = pas_backend_card_sexp_match_contact (sexp, contact);
- g_object_unref(card);
+ g_object_unref(contact);
return retval;
}
@@ -404,7 +396,8 @@ pas_backend_card_sexp_new (const char *text)
if (symbols[i].type == 1) {
e_sexp_add_ifunction(sexp->priv->search_sexp, 0, symbols[i].name,
(ESExpIFunc *)symbols[i].func, sexp->priv->search_context);
- } else {
+ }
+ else {
e_sexp_add_function(sexp->priv->search_sexp, 0, symbols[i].name,
symbols[i].func, sexp->priv->search_context);
}
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h
index eb7c7c6641..7efb697fb0 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.h
+++ b/addressbook/backend/pas/pas-backend-card-sexp.h
@@ -26,7 +26,8 @@
#include <glib.h>
#include <glib-object.h>
-#include <ebook/e-card.h>
+#include <ebook/e-contact.h>
+#include <pas/pas-types.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))
@@ -37,19 +38,19 @@
typedef struct _PASBackendCardSExpPrivate PASBackendCardSExpPrivate;
-typedef struct {
+struct _PASBackendCardSExp {
GObject parent_object;
PASBackendCardSExpPrivate *priv;
-} PASBackendCardSExp;
+};
-typedef struct {
+struct _PASBackendCardSExpClass {
GObjectClass parent_class;
-} PASBackendCardSExpClass;
+};
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);
+gboolean pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact);
#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 b11c62cb86..06923d7b08 100644
--- a/addressbook/backend/pas/pas-backend-file.c
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -8,12 +8,18 @@
#include "config.h"
#include "pas-backend-file.h"
+#include "pas-backend-card-sexp.h"
+#include "pas-backend-summary.h"
+#include "pas-book.h"
+#include "pas-book-view.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <dirent.h>
#include <time.h>
+#include <errno.h>
#include <db.h>
#include <sys/stat.h>
@@ -28,15 +34,12 @@
#include <gal/util/e-util.h>
#include <gal/widgets/e-unicode.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-contact.h>
#include <e-util/e-dbhash.h>
#include <e-util/e-db3-utils.h>
#include <libgnome/gnome-i18n.h>
-#include "pas-book.h"
-#include "pas-card-cursor.h"
-#include "pas-backend-card-sexp.h"
-#include "pas-backend-summary.h"
+#define CHANGES_DB_SUFFIX ".changes.db"
#define PAS_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION"
#define PAS_BACKEND_FILE_VERSION "0.2"
@@ -44,47 +47,17 @@
#define PAS_ID_PREFIX "pas-id-"
#define SUMMARY_FLUSH_TIMEOUT 5000
-static PASBackendClass *pas_backend_file_parent_class;
-typedef struct _PASBackendFileCursorPrivate PASBackendFileCursorPrivate;
-typedef struct _PASBackendFileBookView PASBackendFileBookView;
-typedef struct _PASBackendFileSearchContext PASBackendFileSearchContext;
-typedef struct _PasBackendFileChangeContext PASBackendFileChangeContext;
+static PASBackendSyncClass *pas_backend_file_parent_class;
struct _PASBackendFilePrivate {
char *uri;
+ char *dirname;
char *filename;
+ char *summary_filename;
DB *file_db;
- EList *book_views;
- GHashTable *address_lists;
PASBackendSummary *summary;
};
-struct _PASBackendFileCursorPrivate {
- PASBackend *backend;
- PASBook *book;
-
- GList *elements;
- guint32 num_elements;
-};
-
-struct _PASBackendFileBookView {
- PASBookView *book_view;
- gchar *search;
- PASBackendCardSExp *card_sexp;
- gchar *change_id;
- PASBackendFileChangeContext *change_context;
-};
-
-struct _PasBackendFileChangeContext {
- DB *db;
-
- GList *add_cards;
- GList *add_ids;
- GList *mod_cards;
- GList *mod_ids;
- GList *del_ids;
-};
-
static void
string_to_dbt(const char *str, DBT *dbt)
{
@@ -104,7 +77,8 @@ build_summary (PASBackendFilePrivate *bfpriv)
db_error = db->cursor (db, NULL, &dbc, 0);
if (db_error != 0) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ g_warning ("build_summary: error building list\n");
+ return;
}
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
@@ -117,7 +91,7 @@ build_summary (PASBackendFilePrivate *bfpriv)
if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- pas_backend_summary_add_card (bfpriv->summary, vcard_dbt.data);
+ pas_backend_summary_add_contact (bfpriv->summary, vcard_dbt.data);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -126,21 +100,17 @@ build_summary (PASBackendFilePrivate *bfpriv)
}
static void
-do_summary_query (PASBackendFile *bf,
- PASBackendFileBookView *view,
- gboolean completion_search)
+do_summary_query (PASBackendFile *bf,
+ PASBookView *view)
{
- GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, view->search);
+ GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (view));
int db_error = 0;
- GList *cards = NULL;
- gint card_count = 0, card_threshold = 20, card_threshold_max = 3000;
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int i;
for (i = 0; i < ids->len; i ++) {
char *id = g_ptr_array_index (ids, i);
- char *vcard = NULL;
#if SUMMARY_STORES_ENOUGH_INFO
/* this is disabled for the time being because lists
@@ -150,6 +120,11 @@ do_summary_query (PASBackendFile *bf,
if (completion_search) {
vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary,
id);
+ if (vcard) {
+ EContact *contact = e_contact_new_from_vcard (vcard_dbt.data);
+ pas_book_view_notify_update (view, contact);
+ g_object_unref (contact);
+ }
}
else {
#endif
@@ -159,166 +134,19 @@ do_summary_query (PASBackendFile *bf,
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0)
- vcard = g_strdup (vcard_dbt.data);
+ pas_book_view_notify_update (view, vcard_dbt.data);
#if SUMMARY_STORES_ENOUGH_INFO
}
#endif
-
- if (vcard) {
- cards = g_list_prepend (cards, vcard);
- card_count ++;
-
- /* If we've accumulated a number of checks, pass them off to the client. */
- if (card_count >= card_threshold) {
- pas_book_view_notify_add (view->book_view, cards);
- /* Clean up the handed-off data. */
- g_list_foreach (cards, (GFunc)g_free, NULL);
- g_list_free (cards);
- cards = NULL;
- card_count = 0;
-
- /* Yeah, this scheme is overly complicated. But I like it. */
- if (card_threshold < card_threshold_max) {
- card_threshold = MIN (2*card_threshold, card_threshold_max);
- }
- }
- }
- else
- continue; /* XXX */
}
g_ptr_array_free (ids, TRUE);
- if (card_count)
- pas_book_view_notify_add (view->book_view, cards);
-
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
- g_list_foreach (cards, (GFunc)g_free, NULL);
- g_list_free (cards);
-}
-
-static PASBackendFileBookView *
-pas_backend_file_book_view_copy(const PASBackendFileBookView *book_view, void *closure)
-{
- PASBackendFileBookView *new_book_view;
- new_book_view = g_new (PASBackendFileBookView, 1);
- new_book_view->book_view = book_view->book_view;
-
- new_book_view->search = g_strdup(book_view->search);
- new_book_view->card_sexp = book_view->card_sexp;
- if (new_book_view->card_sexp)
- g_object_ref(new_book_view->card_sexp);
-
- new_book_view->change_id = g_strdup(book_view->change_id);
- if (book_view->change_context) {
- new_book_view->change_context = g_new(PASBackendFileChangeContext, 1);
- new_book_view->change_context->db = book_view->change_context->db;
- new_book_view->change_context->add_cards = book_view->change_context->add_cards;
- new_book_view->change_context->add_ids = book_view->change_context->add_ids;
- new_book_view->change_context->mod_cards = book_view->change_context->mod_cards;
- new_book_view->change_context->mod_ids = book_view->change_context->mod_ids;
- new_book_view->change_context->del_ids = book_view->change_context->del_ids;
- } else
- new_book_view->change_context = NULL;
-
- return new_book_view;
-}
-
-static void
-pas_backend_file_book_view_free(PASBackendFileBookView *book_view, void *closure)
-{
- g_free(book_view->search);
- if (book_view->card_sexp)
- g_object_unref (book_view->card_sexp);
-
- g_free(book_view->change_id);
- if (book_view->change_context) {
- g_list_foreach (book_view->change_context->add_cards, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->add_ids, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->mod_cards, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->mod_ids, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->del_ids, (GFunc)g_free, NULL);
- g_list_free (book_view->change_context->add_cards);
- g_list_free (book_view->change_context->add_ids);
- g_list_free (book_view->change_context->mod_cards);
- g_list_free (book_view->change_context->mod_ids);
- g_list_free (book_view->change_context->del_ids);
- }
- g_free(book_view->change_context);
-
- g_free(book_view);
-}
-
-static long
-get_length(PASCardCursor *cursor, gpointer data)
-{
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
-
- return cursor_data->num_elements;
+ pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
}
static char *
-get_nth(PASCardCursor *cursor, long n, gpointer data)
-{
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
- GList *nth_item = g_list_nth(cursor_data->elements, n);
-
- return g_strdup((char*)nth_item->data);
-}
-
-static void
-cursor_destroy(gpointer data, GObject *where_object_was)
-{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("cursor_destroy: Exception unreffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
-
- g_list_foreach(cursor_data->elements, (GFunc)g_free, NULL);
- g_list_free (cursor_data->elements);
-
- g_free(cursor_data);
-}
-
-static void
-view_destroy(gpointer data, GObject *where_object_was)
-{
- PASBook *book = (PASBook *)data;
- PASBackendFile *bf;
- EIterator *iterator;
- gboolean success = FALSE;
-
- bf = PAS_BACKEND_FILE(pas_book_get_backend(book));
- 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 (view->book_view == (PASBookView*)where_object_was) {
- e_iterator_delete(iterator);
- success = TRUE;
- break;
- }
- }
- if (!success)
- g_warning ("Failed to remove from book_views list");
- g_object_unref(iterator);
-
- bonobo_object_unref(BONOBO_OBJECT(book));
-}
-
-static char *
-pas_backend_file_create_unique_id (char *vcard)
+pas_backend_file_create_unique_id (void)
{
/* use a 32 counter and the 32 bit timestamp to make an id.
it's doubtful 2^32 id's will be created in a second, so we
@@ -327,46 +155,18 @@ pas_backend_file_create_unique_id (char *vcard)
return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++);
}
-static gboolean
-vcard_matches_search (const PASBackendFileBookView *view, char *vcard_string)
-{
- /* 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_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);
-}
-
typedef struct {
PASBackendFile *bf;
PASBook *book;
- const PASBackendFileBookView *view;
+ PASBookView *view;
DBC *dbc;
- int card_count;
- int card_threshold;
- int card_threshold_max;
- GList *cards;
-
gboolean done_first;
- gboolean search_needed;
} FileBackendSearchClosure;
static void
free_search_closure (FileBackendSearchClosure *closure)
{
- g_list_foreach (closure->cards, (GFunc)g_free, NULL);
- g_list_free (closure->cards);
g_free (closure);
}
@@ -397,32 +197,11 @@ pas_backend_file_search_timeout (gpointer data)
/* don't include the version in the list of cards */
if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
char *vcard_string = vcard_dbt.data;
+ EContact *contact = e_contact_new_from_vcard (vcard_string);
- /* check if the vcard matches the search sexp */
- if ((!closure->search_needed) || vcard_matches_search (closure->view, vcard_string)) {
- closure->cards = g_list_prepend (closure->cards, g_strdup (vcard_string));
- closure->card_count ++;
- }
-
- /* If we've accumulated a number of checks, pass them off to the client. */
- if (closure->card_count >= closure->card_threshold) {
- pas_book_view_notify_add (closure->view->book_view, closure->cards);
- /* Clean up the handed-off data. */
- g_list_foreach (closure->cards, (GFunc)g_free, NULL);
- g_list_free (closure->cards);
- closure->cards = NULL;
- closure->card_count = 0;
-
- /* Yeah, this scheme is overly complicated. But I like it. */
- if (closure->card_threshold < closure->card_threshold_max) {
- closure->card_threshold = MIN (2*closure->card_threshold, closure->card_threshold_max);
- }
-
- /* return here, we'll do the next lump in the next callback */
- g_timeout_add (200, pas_backend_file_search_timeout, closure);
-
- return FALSE;
- }
+ /* notify_update will check if it matches for us */
+ pas_book_view_notify_update (closure->view, contact);
+ g_object_unref (contact);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -435,10 +214,7 @@ pas_backend_file_search_timeout (gpointer data)
free_search_closure (closure);
}
- if (closure->card_count)
- pas_book_view_notify_add (closure->view->book_view, closure->cards);
-
- pas_book_view_notify_complete (closure->view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success);
free_search_closure (closure);
@@ -448,49 +224,25 @@ pas_backend_file_search_timeout (gpointer data)
static void
pas_backend_file_search (PASBackendFile *bf,
- PASBook *book,
- const PASBackendFileBookView *cnstview,
- gboolean completion_search)
+ PASBookView *book_view)
{
- PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
- gboolean search_needed;
-
- search_needed = TRUE;
-
- if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")"))
- search_needed = FALSE;
+ const char *query = pas_book_view_get_card_query (book_view);
- if (search_needed)
- pas_book_view_notify_status_message (view->book_view, _("Searching..."));
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ pas_book_view_notify_status_message (book_view, _("Loading..."));
else
- pas_book_view_notify_status_message (view->book_view, _("Loading..."));
-
- if (view->card_sexp) {
- g_object_unref (view->card_sexp);
- view->card_sexp = NULL;
- }
-
- view->card_sexp = pas_backend_card_sexp_new (view->search);
-
- if (!view->card_sexp) {
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery);
- return;
- }
+ pas_book_view_notify_status_message (book_view, _("Searching..."));
- if (pas_backend_summary_is_summary_query (bf->priv->summary, view->search)) {
- do_summary_query (bf, view, completion_search);
+ if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) {
+ do_summary_query (bf, book_view);
}
else {
FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1);
DB *db = bf->priv->file_db;
int db_error;
- closure->card_threshold = 20;
- closure->card_threshold_max = 3000;
- closure->search_needed = search_needed;
- closure->view = view;
+ closure->view = book_view;
closure->bf = bf;
- closure->book = book;
db_error = db->cursor (db, NULL, &closure->dbc, 0);
@@ -502,257 +254,81 @@ pas_backend_file_search (PASBackendFile *bf,
}
}
-static void
-pas_backend_file_changes_foreach_key (const char *key, gpointer user_data)
+static EContact *
+do_create(PASBackendFile *bf,
+ const char *vcard_req)
{
- PASBackendFileChangeContext *ctx = user_data;
- DB *db = ctx->db;
- DBT id_dbt, vcard_dbt;
- int db_error = 0;
-
- string_to_dbt (key, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- if (db_error != 0) {
- char *id = id_dbt.data;
-
- ctx->del_ids = g_list_append (ctx->del_ids, g_strdup (id));
- }
-}
-
-static void
-pas_backend_file_changes (PASBackendFile *bf,
- PASBook *book,
- const PASBackendFileBookView *cnstview)
-{
- int db_error = 0;
- DBT id_dbt, vcard_dbt;
- char *filename;
- EDbHash *ehash;
- GList *i, *v;
- DB *db = bf->priv->file_db;
- DBC *dbc;
- PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
- PASBackendFileChangeContext *ctx = cnstview->change_context;
- char *dirname, *slash;
-
- memset (&id_dbt, 0, sizeof (id_dbt));
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- /* Find the changed ids */
- dirname = g_strdup (bf->priv->filename);
- slash = strrchr (dirname, '/');
- *slash = '\0';
-
- filename = g_strdup_printf ("%s/%s.db", dirname, view->change_id);
- ehash = e_dbhash_new (filename);
- g_free (filename);
- g_free (dirname);
-
- db_error = db->cursor (db, NULL, &dbc, 0);
-
- if (db_error != 0) {
- g_warning ("pas_backend_file_changes: error building list\n");
- } else {
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
-
- while (db_error == 0) {
-
- /* don't include the version in the list of cards */
- if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
- || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- ECard *card;
- char *id = id_dbt.data;
- char *vcard_string;
-
- /* Remove fields the user can't change
- * and can change without the rest of the
- * card changing
- */
- card = e_card_new (vcard_dbt.data);
- g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL);
- vcard_string = e_card_get_vcard_assume_utf8 (card);
- g_object_unref (card);
-
- /* check what type of change has occurred, if any */
- switch (e_dbhash_compare (ehash, id, vcard_string)) {
- case E_DBHASH_STATUS_SAME:
- break;
- case E_DBHASH_STATUS_NOT_FOUND:
- ctx->add_cards = g_list_append (ctx->add_cards,
- vcard_string);
- ctx->add_ids = g_list_append (ctx->add_ids, g_strdup(id));
- break;
- case E_DBHASH_STATUS_DIFFERENT:
- ctx->mod_cards = g_list_append (ctx->mod_cards,
- vcard_string);
- ctx->mod_ids = g_list_append (ctx->mod_ids, g_strdup(id));
- break;
- }
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
- dbc->c_close (dbc);
- }
-
- e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, view->change_context);
-
- /* Send the changes */
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_changes: error building list\n");
- } else {
- if (ctx->add_cards != NULL)
- pas_book_view_notify_add (view->book_view, ctx->add_cards);
-
- if (ctx->mod_cards != NULL)
- pas_book_view_notify_change (view->book_view, ctx->mod_cards);
-
- for (v = ctx->del_ids; v != NULL; v = v->next){
- char *id = v->data;
- pas_book_view_notify_remove_1 (view->book_view, id);
- }
-
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- }
-
- /* Update the hash */
- for (i = ctx->add_ids, v = ctx->add_cards; i != NULL; i = i->next, v = v->next){
- char *id = i->data;
- char *vcard = v->data;
-
- e_dbhash_add (ehash, id, vcard);
- g_free (i->data);
- g_free (v->data);
- }
- for (i = ctx->mod_ids, v = ctx->mod_cards; i != NULL; i = i->next, v = v->next){
- char *id = i->data;
- char *vcard = v->data;
-
- e_dbhash_add (ehash, id, vcard);
- g_free (i->data);
- g_free (v->data);
- }
- for (i = ctx->del_ids; i != NULL; i = i->next){
- char *id = i->data;
-
- e_dbhash_remove (ehash, id);
- g_free (i->data);
- }
-
- e_dbhash_write (ehash);
- e_dbhash_destroy (ehash);
-}
-
-static char *
-do_create(PASBackend *backend,
- char *vcard_req,
- char **vcard_ptr)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
char *id;
- ECard *card;
+ EContact *contact;
char *vcard;
- char *ret_val;
- id = pas_backend_file_create_unique_id (vcard_req);
+ id = pas_backend_file_create_unique_id ();
string_to_dbt (id, &id_dbt);
-
- card = e_card_new(vcard_req);
- e_card_set_id(card, id);
- vcard = e_card_get_vcard_assume_utf8(card);
+
+ contact = e_contact_new_from_vcard (vcard_req);
+ e_contact_set(contact, E_CONTACT_UID, id);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
+ g_free (vcard);
+
if (0 == db_error) {
db_error = db->sync (db, 0);
if (db_error != 0)
g_warning ("db->sync failed.\n");
- ret_val = id;
-
}
else {
- g_free (id);
- ret_val = NULL;
+ g_object_unref (contact);
+ contact = NULL;
}
- g_object_unref(card);
- card = NULL;
-
- if (vcard_ptr && ret_val)
- *vcard_ptr = vcard;
- else
- g_free (vcard);
-
- return ret_val;
+ g_free (id);
+ return contact;
}
-static void
-pas_backend_file_process_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
{
- char *id;
- char *vcard;
- EIterator *iterator;
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- id = do_create(backend, req->vcard, &vcard);
- if (id) {
- 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)) {
- bonobo_object_ref (BONOBO_OBJECT (view->book_view));
- pas_book_view_notify_add_1 (view->book_view, vcard);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- bonobo_object_unref (BONOBO_OBJECT (view->book_view));
- }
- }
- g_object_unref(iterator);
-
- pas_book_respond_create (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- id);
-
- pas_backend_summary_add_card (bf->priv->summary, vcard);
-
- g_free(vcard);
- g_free(id);
+ *contact = do_create (bf, vcard);
+ if (*contact) {
+ pas_backend_summary_add_contact (bf->priv->summary, *contact);
+ return GNOME_Evolution_Addressbook_Success;
}
else {
/* XXX need a different call status for this case, i
think */
- pas_book_respond_create (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound,
- "");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
}
-static void
-pas_backend_file_process_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **ids)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
- EIterator *iterator;
- const char *id;
+ char *id;
GList *l;
GList *removed_cards = NULL;
- GNOME_Evolution_Addressbook_BookListener_CallStatus rv = GNOME_Evolution_Addressbook_BookListener_Success;
+ GNOME_Evolution_Addressbook_CallStatus rv = GNOME_Evolution_Addressbook_Success;
- for (l = req->ids; l; l = l->next) {
+ for (l = id_list; l; l = l->next) {
id = l->data;
string_to_dbt (id, &id_dbt);
@@ -760,17 +336,17 @@ pas_backend_file_process_remove_cards (PASBackend *backend,
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (0 != db_error) {
- rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ rv = GNOME_Evolution_Addressbook_ContactNotFound;
continue;
}
db_error = db->del (db, NULL, &id_dbt, 0);
if (0 != db_error) {
- rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ rv = GNOME_Evolution_Addressbook_ContactNotFound;
continue;
}
- removed_cards = g_list_prepend (removed_cards, e_card_new (vcard_dbt.data));
+ removed_cards = g_list_prepend (removed_cards, id);
}
/* if we actually removed some, try to sync */
@@ -780,53 +356,30 @@ pas_backend_file_process_remove_cards (PASBackend *backend,
g_warning ("db->sync failed.\n");
}
- 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);
- 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, 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, rv);
+ *ids = removed_cards;
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);
+ char *id = l->data;
+ pas_backend_summary_remove_contact (bf->priv->summary, id);
}
- g_list_free (removed_cards);
+ return rv;
}
-static void
-pas_backend_file_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
- EIterator *iterator;
- ECard *card;
- const char *id, *lookup_id;
- char *old_vcard_string;
+ char *id, *lookup_id;
- /* create a new ecard from the request data */
- card = e_card_new(req->vcard);
- id = e_card_get_id(card);
+ *contact = e_contact_new_from_vcard (vcard);
+ id = e_contact_get(*contact, E_CONTACT_UID);
/* This is disgusting, but for a time cards were added with
ID's that are no longer used (they contained both the uri
@@ -844,15 +397,10 @@ pas_backend_file_process_modify_card (PASBackend *backend,
/* get the old ecard - the one that's presently in the db */
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
- old_vcard_string = g_strdup(vcard_dbt.data);
+ if (0 != db_error)
+ return GNOME_Evolution_Addressbook_ContactNotFound;
- string_to_dbt (req->vcard, &vcard_dbt);
+ string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
@@ -861,55 +409,50 @@ pas_backend_file_process_modify_card (PASBackend *backend,
if (db_error != 0)
g_warning ("db->sync failed.\n");
- for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- CORBA_Environment ev;
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- gboolean old_match, new_match;
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- old_match = vcard_matches_search (view, old_vcard_string);
- new_match = vcard_matches_search (view, req->vcard);
- if (old_match && new_match)
- pas_book_view_notify_change_1 (view->book_view, req->vcard);
- else if (new_match)
- pas_book_view_notify_add_1 (view->book_view, req->vcard);
- else /* if (old_match) */
- pas_book_view_notify_remove_1 (view->book_view, id);
+ pas_backend_summary_remove_contact (bf->priv->summary, id);
+ pas_backend_summary_add_contact (bf->priv->summary, *contact);
+ }
+ g_free (id);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ if (0 == db_error)
+ return GNOME_Evolution_Addressbook_Success;
+ else
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+}
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
+static PASBackendSyncStatus
+pas_backend_file_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ PASBackendFile *bf;
+ DB *db;
+ DBT id_dbt, vcard_dbt;
+ int db_error = 0;
- CORBA_exception_free (&ev);
- }
+ bf = PAS_BACKEND_FILE (pas_book_get_backend (book));
+ db = bf->priv->file_db;
- g_object_unref(iterator);
+ string_to_dbt (id, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success);
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- pas_backend_summary_remove_card (bf->priv->summary, id);
- pas_backend_summary_add_card (bf->priv->summary, req->vcard);
- }
- else {
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
+ if (db_error == 0) {
+ *vcard = g_strdup (vcard_dbt.data);
+ return GNOME_Evolution_Addressbook_Success;
+ } else {
+ *vcard = g_strdup ("");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
-
- g_free(old_vcard_string);
-
- g_object_unref(card);
}
-static void
-pas_backend_file_build_cards_list(PASBackend *backend,
- PASBackendFileCursorPrivate *cursor_data,
- char *search)
+static PASBackendSyncStatus
+pas_backend_file_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
@@ -918,8 +461,10 @@ pas_backend_file_build_cards_list(PASBackend *backend,
DBT id_dbt, vcard_dbt;
PASBackendCardSExp *card_sexp = NULL;
gboolean search_needed;
-
- cursor_data->elements = NULL;
+ const char *search = query;
+ GList *contact_list = NULL;
+
+ printf ("pas_backend_file_get_contact_list (%s)\n", search);
search_needed = TRUE;
@@ -927,14 +472,16 @@ pas_backend_file_build_cards_list(PASBackend *backend,
search_needed = FALSE;
card_sexp = pas_backend_card_sexp_new (search);
-
- if (!card_sexp)
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ if (!card_sexp) {
+ /* XXX this needs to be an invalid query error of some sort*/
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
db_error = db->cursor (db, NULL, &dbc, 0);
if (db_error != 0) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ /* XXX this needs to be some CouldNotOpen error */
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
@@ -948,7 +495,7 @@ pas_backend_file_build_cards_list(PASBackend *backend,
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
if ((!search_needed) || (card_sexp != NULL && pas_backend_card_sexp_match_vcard (card_sexp, vcard_dbt.data))) {
- cursor_data->elements = g_list_prepend (cursor_data->elements, g_strdup (vcard_dbt.data));
+ contact_list = g_list_append (contact_list, g_strdup (vcard_dbt.data));
}
}
@@ -956,274 +503,211 @@ pas_backend_file_build_cards_list(PASBackend *backend,
}
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
- }
- else {
- cursor_data->num_elements = g_list_length (cursor_data->elements);
- cursor_data->elements = g_list_reverse (cursor_data->elements);
- }
+ *contacts = contact_list;
+ return db_error != DB_NOTFOUND
+ ? GNOME_Evolution_Addressbook_OtherError
+ : GNOME_Evolution_Addressbook_Success;
}
static void
-pas_backend_file_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_file_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
{
- PASBackendFile *bf;
- DB *db;
- DBT id_dbt, vcard_dbt;
- int db_error = 0;
- char *card;
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
-
- bf = PAS_BACKEND_FILE (pas_book_get_backend (book));
- db = bf->priv->file_db;
-
- string_to_dbt (req->id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
+ pas_backend_file_search (PAS_BACKEND_FILE (backend), book_view);
+}
- if (db_error == 0) {
- card = vcard_dbt.data;
- status = GNOME_Evolution_Addressbook_BookListener_Success;
- } else {
- card = "";
- status = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
- }
+typedef struct {
+ DB *db;
- pas_book_respond_get_vcard (book,
- status,
- card);
-}
+ GList *add_cards;
+ GList *add_ids;
+ GList *mod_cards;
+ GList *mod_ids;
+ GList *del_ids;
+} PASBackendFileChangeContext;
static void
-pas_backend_file_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
+pas_backend_file_changes_foreach_key (const char *key, gpointer user_data)
{
- /*
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- DB *db = bf->priv->file_db;
- DBT id_dbt, vcard_dbt;
- */
- CORBA_Environment ev;
- int db_error = 0;
- PASBackendFileCursorPrivate *cursor_data;
- PASCardCursor *cursor;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- cursor_data = g_new(PASBackendFileCursorPrivate, 1);
- cursor_data->backend = backend;
- cursor_data->book = book;
-
- pas_backend_file_build_cards_list(backend, cursor_data, req->search);
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev);
+ PASBackendFileChangeContext *ctx = user_data;
+ DB *db = ctx->db;
+ DBT id_dbt, vcard_dbt;
+ int db_error = 0;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("pas_backend_file_process_get_cursor: Exception reffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
+ string_to_dbt (key, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- cursor = pas_card_cursor_new(get_length,
- get_nth,
- cursor_data);
+ if (db_error != 0) {
+ char *id = id_dbt.data;
- g_object_weak_ref (G_OBJECT (cursor),
- cursor_destroy, cursor_data);
-
- pas_book_respond_get_cursor (
- book,
- (db_error == 0
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound),
- cursor);
+ ctx->del_ids = g_list_append (ctx->del_ids,
+ g_strdup (id));
+ }
}
-static void
-pas_backend_file_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_get_changes (PASBackendSync *backend,
+ PASBook *book,
+ const char *change_id,
+ GList **changes_out)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- EIterator *iterator;
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- view.book_view = book_view;
- view.search = g_strdup (req->search);
- view.card_sexp = NULL;
- view.change_id = NULL;
- view.change_context = NULL;
-
- e_list_append(bf->priv->book_views, &view);
-
- pas_book_respond_get_book_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- if (!pas_backend_is_loaded (backend))
- return;
+ int db_error = 0;
+ DBT id_dbt, vcard_dbt;
+ char *filename;
+ EDbHash *ehash;
+ GList *i, *v;
+ DB *db = bf->priv->file_db;
+ DBC *dbc;
+ GList *changes = NULL;
+ PASBackendFileChangeContext ctx;
+ PASBackendSyncStatus result;
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE);
- g_object_unref(iterator);
-}
+ memset (&id_dbt, 0, sizeof (id_dbt));
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-static void
-pas_backend_file_process_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- EIterator *iterator;
+ memset (&ctx, 0, sizeof (ctx));
- bonobo_object_ref(BONOBO_OBJECT(book));
+ ctx.db = db;
- book_view = pas_book_view_new (req->listener);
+ /* Find the changed ids */
+ filename = g_strdup_printf ("%s/%s" CHANGES_DB_SUFFIX, bf->priv->dirname, change_id);
+ ehash = e_dbhash_new (filename);
+ g_free (filename);
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
+ db_error = db->cursor (db, NULL, &dbc, 0);
- view.book_view = book_view;
- view.search = g_strdup (req->search);
- view.card_sexp = NULL;
- view.change_id = NULL;
- view.change_context = NULL;
+ if (db_error != 0) {
+ g_warning ("pas_backend_file_changes: error building list\n");
+ } else {
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
- e_list_append(bf->priv->book_views, &view);
+ while (db_error == 0) {
- pas_book_respond_get_completion_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
+ /* don't include the version in the list of cards */
+ if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
+ || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
+ EContact *contact;
+ char *id = id_dbt.data;
+ char *vcard_string;
+
+ /* Remove fields the user can't change
+ * and can change without the rest of the
+ * card changing
+ */
+ contact = e_contact_new_from_vcard (vcard_dbt.data);
+#if notyet
+ g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL);
+#endif
+ vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ g_object_unref (contact);
+
+ /* check what type of change has occurred, if any */
+ switch (e_dbhash_compare (ehash, id, vcard_string)) {
+ case E_DBHASH_STATUS_SAME:
+ break;
+ case E_DBHASH_STATUS_NOT_FOUND:
+ ctx.add_cards = g_list_append (ctx.add_cards, vcard_string);
+ ctx.add_ids = g_list_append (ctx.add_ids, g_strdup(id));
+ break;
+ case E_DBHASH_STATUS_DIFFERENT:
+ ctx.mod_cards = g_list_append (ctx.mod_cards, vcard_string);
+ ctx.mod_ids = g_list_append (ctx.mod_ids, g_strdup(id));
+ break;
+ }
+ }
- if (!pas_backend_is_loaded (backend))
- return;
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
+ }
+ dbc->c_close (dbc);
+ }
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE);
- g_object_unref(iterator);
-}
+ e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, &ctx);
-static void
-pas_backend_file_process_get_changes (PASBackend *backend,
- PASBook *book,
- PASGetChangesRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- PASBackendFileChangeContext ctx;
- EIterator *iterator;
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- pas_book_respond_get_changes (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- view.book_view = book_view;
- view.change_id = req->change_id;
- view.change_context = &ctx;
- ctx.db = bf->priv->file_db;
- ctx.add_cards = NULL;
- ctx.add_ids = NULL;
- ctx.mod_cards = NULL;
- ctx.mod_ids = NULL;
- ctx.del_ids = NULL;
- view.search = NULL;
- view.card_sexp = NULL;
-
- e_list_append(bf->priv->book_views, &view);
+ /* Send the changes */
+ if (db_error != DB_NOTFOUND) {
+ g_warning ("pas_backend_file_changes: error building list\n");
+ *changes_out = NULL;
+ result = GNOME_Evolution_Addressbook_OtherError;
+ }
+ else {
+ /* Update the hash and build our changes list */
+ for (i = ctx.add_ids, v = ctx.add_cards; i != NULL; i = i->next, v = v->next){
+ char *id = i->data;
+ char *vcard = v->data;
+
+ e_dbhash_add (ehash, id, vcard);
+ changes = g_list_prepend (changes,
+ pas_backend_change_add_new (vcard));
+
+ g_free (i->data);
+ g_free (v->data);
+ }
+ for (i = ctx.mod_ids, v = ctx.mod_cards; i != NULL; i = i->next, v = v->next){
+ char *id = i->data;
+ char *vcard = v->data;
+
+ e_dbhash_add (ehash, id, vcard);
+ changes = g_list_prepend (changes,
+ pas_backend_change_modify_new (vcard));
+
+ g_free (i->data);
+ g_free (v->data);
+ }
+ for (i = ctx.del_ids; i != NULL; i = i->next){
+ char *id = i->data;
+
+ e_dbhash_remove (ehash, id);
+ changes = g_list_prepend (changes,
+ pas_backend_change_delete_new (id));
+ g_free (i->data);
+ }
- if (!pas_backend_is_loaded (backend))
- return;
+ e_dbhash_write (ehash);
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_changes (bf, book, e_iterator_get(iterator));
- g_object_unref(iterator);
-}
+ result = GNOME_Evolution_Addressbook_Success;
+ *changes_out = changes;
+ }
-static void
-pas_backend_file_process_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ e_dbhash_destroy (ehash);
- pas_book_report_connection (book, bf->priv->file_db != NULL);
+ return GNOME_Evolution_Addressbook_Success;
}
static char *
pas_backend_file_extract_path_from_uri (const char *uri)
{
- g_assert (strncasecmp (uri, "file:", 5) == 0);
+ g_assert (strncasecmp (uri, "file://", 7) == 0);
- return g_strdup (uri + 5);
+ return g_strdup (uri + 7);
}
-static void
-pas_backend_file_process_authenticate_user (PASBackend *backend,
- PASBook *book,
- PASAuthenticateUserRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
- pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_Success);
+ return GNOME_Evolution_Addressbook_Success;
}
-static void
-pas_backend_file_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields_out)
{
- EList *fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
- ECardSimple *simple;
- ECard *card;
+ GList *fields = NULL;
int i;
- /* we support everything, so instantiate an e-card, and loop
- through all fields, adding their ecard_fields. */
+ /* XXX we need a way to say "we support everything", since the
+ file backend does */
+ for (i = 1; i < E_CONTACT_FIELD_LAST; i ++)
+ fields = g_list_append (fields, g_strdup (e_contact_field_name (i)));
- card = e_card_new ("");
- simple = e_card_simple_new (card);
-
- for (i = 0; i < E_CARD_SIMPLE_FIELD_LAST; i ++)
- e_list_append (fields, e_card_simple_get_ecard_field (simple, i));
-
- g_object_unref (card);
- g_object_unref (simple);
-
- pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- fields);
+ *fields_out = fields;
+ return GNOME_Evolution_Addressbook_Success;
}
/*
@@ -1273,9 +757,9 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
while (db_error == 0) {
if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- ECard *card;
+ EContact *contact;
- card = e_card_new (vcard_dbt.data);
+ contact = e_contact_new_from_vcard (vcard_dbt.data);
/* the cards we're looking for are
created with a normal id dbt, but
@@ -1283,12 +767,12 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
to something that doesn't match.
so, we need to modify the card to
have the same id as the the dbt. */
- if (strcmp (id_dbt.data, e_card_get_id (card))) {
+ if (strcmp (id_dbt.data, e_contact_get_const (contact, E_CONTACT_UID))) {
char *vcard;
- e_card_set_id (card, id_dbt.data);
+ e_contact_set (contact, E_CONTACT_UID, id_dbt.data);
- vcard = e_card_get_vcard (card);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL,
@@ -1300,7 +784,7 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
card_failed++;
}
- g_object_unref (card);
+ g_object_unref (contact);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -1352,30 +836,21 @@ pas_backend_file_maybe_upgrade_db (PASBackendFile *bf)
return ret_val;
}
-#define INITIAL_VCARD "BEGIN:VCARD\n\
-X-EVOLUTION-FILE-AS:Ximian, Inc.\n\
-LABEL;WORK;QUOTED-PRINTABLE:401 Park Drive 3 West=0ABoston, MA 02215=0AUSA\n\
-TEL;WORK;VOICE:(617) 375-3800\n\
-TEL;WORK;FAX:(617) 236-8630\n\
-EMAIL;INTERNET:hello@ximian.com\n\
-URL:www.ximian.com/\n\
-ORG:Ximian, Inc.;\n\
-NOTE:Welcome to the Ximian Addressbook.\n\
-END:VCARD"
-
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+#include "ximian-vcard.h"
+
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_file_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- char *filename;
+ char *dirname, *filename;
gboolean writable = FALSE;
int db_error;
DB *db;
int major, minor, patch;
time_t db_mtime;
struct stat sb;
- char *summary_filename;
g_free(bf->priv->uri);
bf->priv->uri = g_strdup (uri);
@@ -1386,18 +861,19 @@ pas_backend_file_load_uri (PASBackend *backend,
minor != 1 ||
patch != 17) {
g_warning ("Wrong version of libdb.");
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
- filename = pas_backend_file_extract_path_from_uri (uri);
+ dirname = pas_backend_file_extract_path_from_uri (uri);
+ filename = g_build_filename (dirname, "addressbook.db", NULL);
db_error = e_db3_utils_maybe_recover (filename);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db_create (&db, NULL, 0);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
@@ -1405,7 +881,7 @@ pas_backend_file_load_uri (PASBackend *backend,
db_error = e_db3_utils_upgrade_format (filename);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
}
@@ -1418,23 +894,27 @@ pas_backend_file_load_uri (PASBackend *backend,
db_error = db->open (db, filename, NULL, DB_HASH, DB_RDONLY, 0666);
if (db_error != 0) {
- db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666);
-
- if (db_error == 0) {
- char *create_initial_file;
- char *dir;
+ int rv;
+
+ /* the database didn't exist, so we create the
+ directory then the .db */
+ rv = mkdir (dirname, 0777);
+ if (rv == -1 && errno != EEXIST) {
+ g_warning ("failed to make directory %s: %s", dirname, strerror (errno));
+ if (errno == EACCES || errno == EPERM)
+ return GNOME_Evolution_Addressbook_PermissionDenied;
+ else
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
- dir = g_path_get_dirname(filename);
- create_initial_file = g_build_filename (dir, "create-initial", NULL);
+ db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666);
- if (g_file_test(create_initial_file, G_FILE_TEST_EXISTS)) {
- char *id;
- id = do_create(backend, INITIAL_VCARD, NULL);
- g_free (id);
- }
+ if (db_error == 0 && !only_if_exists) {
+ EContact *contact;
- g_free(create_initial_file);
- g_free(dir);
+ contact = do_create(bf, XIMIAN_VCARD);
+ /* XXX check errors here */
+ g_object_unref (contact);
writable = TRUE;
}
@@ -1443,28 +923,30 @@ pas_backend_file_load_uri (PASBackend *backend,
if (db_error != 0) {
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
if (!pas_backend_file_maybe_upgrade_db (bf)) {
db->close (db, 0);
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
+ g_free (bf->priv->dirname);
g_free (bf->priv->filename);
+ bf->priv->dirname = dirname;
bf->priv->filename = filename;
if (stat (bf->priv->filename, &sb) == -1) {
db->close (db, 0);
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
db_mtime = sb.st_mtime;
- summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL);
- bf->priv->summary = pas_backend_summary_new (summary_filename, SUMMARY_FLUSH_TIMEOUT);
- g_free (summary_filename);
+ g_free (bf->priv->summary_filename);
+ bf->priv->summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL);
+ bf->priv->summary = pas_backend_summary_new (bf->priv->summary_filename, SUMMARY_FLUSH_TIMEOUT);
if (pas_backend_summary_is_up_to_date (bf->priv->summary, db_mtime) == FALSE
|| pas_backend_summary_load (bf->priv->summary) == FALSE ) {
@@ -1473,20 +955,76 @@ pas_backend_file_load_uri (PASBackend *backend,
pas_backend_set_is_loaded (backend, TRUE);
pas_backend_set_is_writable (backend, writable);
- return GNOME_Evolution_Addressbook_BookListener_Success;
+
+ return GNOME_Evolution_Addressbook_Success;
}
-/* Get_uri handler for the addressbook file backend */
-static const char *
-pas_backend_file_get_uri (PASBackend *backend)
+static int
+select_changes (const struct dirent *d)
{
- PASBackendFile *bf;
+ char *p;
+
+ if (strlen (d->d_name) < strlen (CHANGES_DB_SUFFIX))
+ return 0;
+
+ p = strstr (d->d_name, CHANGES_DB_SUFFIX);
+ if (!p)
+ return 0;
+
+ if (strlen (p) != strlen (CHANGES_DB_SUFFIX))
+ return 0;
+
+ return 1;
+}
+
+static PASBackendSyncStatus
+pas_backend_file_remove (PASBackendSync *backend,
+ PASBook *book)
+{
+ PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ struct dirent **namelist;
+ int n;
+
+ if (-1 == unlink (bf->priv->filename)) {
+ if (errno == EACCES || errno == EPERM)
+ return GNOME_Evolution_Addressbook_PermissionDenied;
+ else
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
- bf = PAS_BACKEND_FILE (backend);
+ /* unref the summary before we remove the file so it's not written out again */
+ g_object_unref (bf->priv->summary);
+ bf->priv->summary = NULL;
+ if (-1 == unlink (bf->priv->filename))
+ g_warning ("failed to remove summary file `%s`: %s", bf->priv->summary_filename, strerror (errno));
+
+ /* scandir to select all the "*.changes.db" files, then remove them */
+ n = scandir (bf->priv->dirname,
+ &namelist, select_changes, alphasort);
+ if (n < 0) {
+ g_warning ("scandir of directory `%s' failed: %s", bf->priv->dirname, strerror (errno));
+ }
+ else {
+ while (n -- ) {
+ char *full_path = g_build_filename (bf->priv->dirname, namelist[n]->d_name, NULL);
+ if (-1 == unlink (full_path)) {
+ g_warning ("failed to remove change db `%s': %s", full_path, strerror (errno));
+ }
+ g_free (full_path);
+ free (namelist[n]);
+ }
+ free (namelist);
+ }
- g_assert (bf->priv->uri != NULL);
+ if (-1 == rmdir (bf->priv->dirname))
+ g_warning ("failed to remove directory `%s`: %s", bf->priv->dirname, strerror (errno));
- return bf->priv->uri;
+ /* we may not have actually succeeded in removing the
+ backend's files/dirs, but there's nothing we can do about
+ it here.. the only time we should return failure is if we
+ failed to remove the actual data. a failure should mean
+ that the addressbook is still valid */
+ return GNOME_Evolution_Addressbook_Success;
}
static char *
@@ -1495,6 +1033,12 @@ pas_backend_file_get_static_capabilities (PASBackend *backend)
return g_strdup("local,do-initial-query,bulk-removes");
}
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_file_cancel_operation (PASBackend *backend, PASBook *book)
+{
+ return GNOME_Evolution_Addressbook_CouldNotCancel;
+}
+
static gboolean
pas_backend_file_construct (PASBackendFile *backend)
{
@@ -1534,11 +1078,12 @@ pas_backend_file_dispose (GObject *object)
bf = PAS_BACKEND_FILE (object);
if (bf->priv) {
- g_object_unref(bf->priv->book_views);
if (bf->priv->summary)
g_object_unref(bf->priv->summary);
g_free (bf->priv->uri);
g_free (bf->priv->filename);
+ g_free (bf->priv->dirname);
+ g_free (bf->priv->summary_filename);
g_free (bf->priv);
bf->priv = NULL;
@@ -1551,28 +1096,29 @@ static void
pas_backend_file_class_init (PASBackendFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- PASBackendClass *parent_class;
+ PASBackendSyncClass *sync_class;
+ PASBackendClass *backend_class;
pas_backend_file_parent_class = g_type_class_peek_parent (klass);
- parent_class = PAS_BACKEND_CLASS (klass);
+ sync_class = PAS_BACKEND_SYNC_CLASS (klass);
+ backend_class = PAS_BACKEND_CLASS (klass);
/* Set the virtual methods. */
- parent_class->load_uri = pas_backend_file_load_uri;
- parent_class->get_uri = pas_backend_file_get_uri;
- parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
-
- parent_class->create_card = pas_backend_file_process_create_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;
- parent_class->get_cursor = pas_backend_file_process_get_cursor;
- parent_class->get_book_view = pas_backend_file_process_get_book_view;
- parent_class->get_completion_view = pas_backend_file_process_get_completion_view;
- parent_class->get_changes = pas_backend_file_process_get_changes;
- parent_class->authenticate_user = pas_backend_file_process_authenticate_user;
- parent_class->get_supported_fields = pas_backend_file_process_get_supported_fields;
+ backend_class->load_uri = pas_backend_file_load_uri;
+ backend_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
+ backend_class->start_book_view = pas_backend_file_start_book_view;
+ backend_class->cancel_operation = pas_backend_file_cancel_operation;
+
+ sync_class->remove_sync = pas_backend_file_remove;
+ sync_class->create_contact_sync = pas_backend_file_create_contact;
+ sync_class->remove_contacts_sync = pas_backend_file_remove_contacts;
+ sync_class->modify_contact_sync = pas_backend_file_modify_contact;
+ sync_class->get_contact_sync = pas_backend_file_get_contact;
+ sync_class->get_contact_list_sync = pas_backend_file_get_contact_list;
+ sync_class->get_changes_sync = pas_backend_file_get_changes;
+ sync_class->authenticate_user_sync = pas_backend_file_authenticate_user;
+ sync_class->get_supported_fields_sync = pas_backend_file_get_supported_fields;
object_class->dispose = pas_backend_file_dispose;
}
@@ -1583,7 +1129,6 @@ pas_backend_file_init (PASBackendFile *backend)
PASBackendFilePrivate *priv;
priv = g_new0 (PASBackendFilePrivate, 1);
- priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL);
priv->uri = NULL;
backend->priv = priv;
@@ -1610,7 +1155,7 @@ pas_backend_file_get_type (void)
(GInstanceInitFunc) pas_backend_file_init
};
- type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendFile", &info, 0);
+ type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendFile", &info, 0);
}
return type;
diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h
index fd98d2cdd5..6e1a77b119 100644
--- a/addressbook/backend/pas/pas-backend-file.h
+++ b/addressbook/backend/pas/pas-backend-file.h
@@ -5,7 +5,7 @@
#ifndef __PAS_BACKEND_FILE_H__
#define __PAS_BACKEND_FILE_H__
-#include "pas-backend.h"
+#include "pas-backend-sync.h"
#define PAS_TYPE_BACKEND_FILE (pas_backend_file_get_type ())
#define PAS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_FILE, PASBackendFile))
@@ -17,12 +17,12 @@
typedef struct _PASBackendFilePrivate PASBackendFilePrivate;
typedef struct {
- PASBackend parent_object;
+ PASBackendSync parent_object;
PASBackendFilePrivate *priv;
} PASBackendFile;
typedef struct {
- PASBackendClass parent_class;
+ PASBackendSyncClass parent_class;
} PASBackendFileClass;
PASBackend *pas_backend_file_new (void);
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
index 1e8677e559..9c44e9983f 100644
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ b/addressbook/backend/pas/pas-backend-ldap.c
@@ -34,13 +34,13 @@
#include <sys/time.h>
#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-contact.h>
#include <libgnome/gnome-i18n.h>
#include "pas-backend-ldap.h"
#include "pas-backend-card-sexp.h"
#include "pas-book.h"
-#include "pas-card-cursor.h"
+#include "pas-book-view.h"
#include <stdlib.h>
@@ -59,14 +59,6 @@ typedef enum {
/* timeout for ldap_result */
#define LDAP_RESULT_TIMEOUT_MILLIS 10
-/* smart grouping stuff */
-#define GROUPING_INITIAL_SIZE 1
-#define GROUPING_MAXIMUM_SIZE 200
-
-/* the next two are in milliseconds */
-#define GROUPING_MINIMUM_WAIT 0 /* we never send updates faster than this, to avoid totally spamming the UI */
-#define GROUPING_MAXIMUM_WAIT 250 /* we always send updates (if there are pending cards) when we hit this */
-
#define TV_TO_MILLIS(timeval) ((timeval).tv_sec * 1000 + (timeval).tv_usec / 1000)
/* the objectClasses we need */
@@ -107,12 +99,10 @@ struct _PASBackendLDAPPrivate {
was not built into openldap. */
PASBackendLDAPUseTLS use_tls;
- EList *book_views;
-
LDAP *ldap;
- EList *supported_fields;
- EList *supported_auth_methods;
+ GList *supported_fields;
+ GList *supported_auth_methods;
/* whether or not there's support for the objectclass we need
to store all our additional fields */
@@ -138,7 +128,6 @@ struct _PASBackendLDAPBookView {
PASBookView *book_view;
PASBackendLDAPPrivate *blpriv;
gchar *search;
- PASBackendCardSExp *card_sexp;
int limit;
LDAPOp *search_op;
@@ -160,122 +149,129 @@ static void ldap_op_add (LDAPOp *op, PASBackend *backend, PASBook *book,
PASBookView *view, int id, LDAPOpHandler handler, LDAPOpDtor dtor);
static void ldap_op_finished (LDAPOp *op);
-static void ldap_search_op_timeout (LDAPOp *op, glong cur_millis);
-
static gboolean poll_ldap (PASBackendLDAP *bl);
-static ECardSimple *build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses);
+static EContact *build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses);
+
+static void email_populate (EContact *contact, char **values);
+struct berval** email_ber (EContact *contact);
+static gboolean email_compare (EContact *contact1, EContact *contact2);
-static void email_populate (ECardSimple *card, char **values);
-struct berval** email_ber (ECardSimple *card);
-static gboolean email_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void homephone_populate (EContact *contact, char **values);
+struct berval** homephone_ber (EContact *contact);
+static gboolean homephone_compare (EContact *contact1, EContact *contact2);
-static void homephone_populate (ECardSimple *card, char **values);
-struct berval** homephone_ber (ECardSimple *card);
-static gboolean homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void business_populate (EContact *contact, char **values);
+struct berval** business_ber (EContact *contact);
+static gboolean business_compare (EContact *contact1, EContact *contact2);
-static void business_populate (ECardSimple *card, char **values);
-struct berval** business_ber (ECardSimple *card);
-static gboolean business_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void anniversary_populate (EContact *contact, char **values);
+struct berval** anniversary_ber (EContact *contact);
+static gboolean anniversary_compare (EContact *contact1, EContact *contact2);
-static void anniversary_populate (ECardSimple *card, char **values);
-struct berval** anniversary_ber (ECardSimple *card);
-static gboolean anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void birthday_populate (EContact *contact, char **values);
+struct berval** birthday_ber (EContact *contact);
+static gboolean birthday_compare (EContact *contact1, EContact *contact2);
-static void birthday_populate (ECardSimple *card, char **values);
-struct berval** birthday_ber (ECardSimple *card);
-static gboolean birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void category_populate (EContact *contact, char **values);
+struct berval** category_ber (EContact *contact);
+static gboolean category_compare (EContact *contact1, EContact *contact2);
-static void category_populate (ECardSimple *card, char **values);
-struct berval** category_ber (ECardSimple *card);
-static gboolean category_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void photo_populate (EContact *contact, struct berval **ber_values);
struct prop_info {
- ECardSimpleField field_id;
- char *query_prop;
+ EContactField field_id;
char *ldap_attr;
#define PROP_TYPE_STRING 0x01
-#define PROP_TYPE_COMPLEX 0x02
-#define PROP_DN 0x04
-#define PROP_EVOLVE 0x08
+#define PROP_TYPE_COMPLEX 0x02
+#define PROP_TYPE_BINARY 0x04
+#define PROP_DN 0x08
+#define PROP_EVOLVE 0x10
+#define PROP_WRITE_ONLY 0x20
int prop_type;
/* the remaining items are only used for the TYPE_COMPLEX props */
- /* used when reading from the ldap server populates ECard with the values in **values. */
- void (*populate_ecard_func)(ECardSimple *card, char **values);
+ /* used when reading from the ldap server populates EContact with the values in **values. */
+ void (*populate_contact_func)(EContact *contact, char **values);
/* used when writing to an ldap server. returns a NULL terminated array of berval*'s */
- struct berval** (*ber_func)(ECardSimple *card);
+ struct berval** (*ber_func)(EContact *contact);
/* used to compare list attributes */
- gboolean (*compare_func)(ECardSimple *card1, ECardSimple *card2);
+ gboolean (*compare_func)(EContact *contact1, EContact *contact2);
+
+ void (*binary_populate_contact_func)(EContact *contact, struct berval **ber_values);
} prop_info[] = {
-#define COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX, ctor, ber, cmp}
-#define E_COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp}
-#define STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING}
-#define E_STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING | PROP_EVOLVE}
+#define BINARY_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_BINARY, NULL, ber, cmp, ctor}
+#define COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX, ctor, ber, cmp}
+#define E_COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp}
+#define STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING}
+#define WRITE_ONLY_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_WRITE_ONLY}
+#define E_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_EVOLVE}
/* name fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", "cn" ),
- STRING_PROP (E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", "sn" ),
+ STRING_PROP (E_CONTACT_FULL_NAME, "cn" ),
+ WRITE_ONLY_STRING_PROP (E_CONTACT_FAMILY_NAME, "sn" ),
/* email addresses */
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_EMAIL, "email", "mail", email_populate, email_ber, email_compare),
+ COMPLEX_PROP (E_CONTACT_EMAIL, "mail", email_populate, email_ber, email_compare),
/* phone numbers */
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, "primary_phone", "primaryPhone"),
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, "business_phone", "telephoneNumber", business_populate, business_ber, business_compare),
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME, "home_phone", "homePhone", homephone_populate, homephone_ber, homephone_compare),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_MOBILE, "mobile_phone", "mobile"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CAR, "car_phone", "carPhone"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, "business_fax", "facsimileTelephoneNumber"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, "home_fax", "homeFacsimileTelephoneNumber"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER, "other_phone", "otherPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, "other_fax", "otherFacsimileTelephoneNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ISDN, "isdn", "internationaliSDNNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PAGER, "pager", "pager"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_RADIO, "radio", "radio"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TELEX, "telex", "telex"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, "assistant_phone", "assistantPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_COMPANY, "company_phone", "companyPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, "callback_phone", "callbackPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, "tty", "tty"),
+ E_STRING_PROP (E_CONTACT_PHONE_PRIMARY, "primaryPhone"),
+ COMPLEX_PROP (E_CONTACT_PHONE_BUSINESS, "telephoneNumber", business_populate, business_ber, business_compare),
+ COMPLEX_PROP (E_CONTACT_PHONE_HOME, "homePhone", homephone_populate, homephone_ber, homephone_compare),
+ STRING_PROP (E_CONTACT_PHONE_MOBILE, "mobile"),
+ E_STRING_PROP (E_CONTACT_PHONE_CAR, "carPhone"),
+ STRING_PROP (E_CONTACT_PHONE_BUSINESS_FAX, "facsimileTelephoneNumber"),
+ E_STRING_PROP (E_CONTACT_PHONE_HOME_FAX, "homeFacsimileTelephoneNumber"),
+ E_STRING_PROP (E_CONTACT_PHONE_OTHER, "otherPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_OTHER_FAX, "otherFacsimileTelephoneNumber"),
+ STRING_PROP (E_CONTACT_PHONE_ISDN, "internationaliSDNNumber"),
+ STRING_PROP (E_CONTACT_PHONE_PAGER, "pager"),
+ E_STRING_PROP (E_CONTACT_PHONE_RADIO, "radio"),
+ E_STRING_PROP (E_CONTACT_PHONE_TELEX, "telex"),
+ E_STRING_PROP (E_CONTACT_PHONE_ASSISTANT, "assistantPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_COMPANY, "companyPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_CALLBACK, "callbackPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_TTYTDD, "tty"),
/* org information */
- STRING_PROP (E_CARD_SIMPLE_FIELD_ORG, "org", "o"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "ou"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_OFFICE, "office", "roomNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_TITLE, "title", "title"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ROLE, "role", "businessRole"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_MANAGER, "manager", "managerName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistantName"),
+ STRING_PROP (E_CONTACT_ORG, "o"),
+ STRING_PROP (E_CONTACT_ORG_UNIT, "ou"),
+ STRING_PROP (E_CONTACT_OFFICE, "roomNumber"),
+ STRING_PROP (E_CONTACT_TITLE, "title"),
+ E_STRING_PROP (E_CONTACT_ROLE, "businessRole"),
+ E_STRING_PROP (E_CONTACT_MANAGER, "managerName"),
+ E_STRING_PROP (E_CONTACT_ASSISTANT, "assistantName"),
/* addresses */
- STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, "business_address", "postalAddress"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_HOME, "home_address", "homePostalAddress"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, "other_address", "otherPostalAddress"),
+ STRING_PROP (E_CONTACT_ADDRESS_LABEL_WORK, "postalAddress"),
+ STRING_PROP (E_CONTACT_ADDRESS_LABEL_HOME, "homePostalAddress"),
+ E_STRING_PROP (E_CONTACT_ADDRESS_LABEL_OTHER, "otherPostalAddress"),
+
+ /* photos */
+ BINARY_PROP (E_CONTACT_PHOTO, "jpegPhoto", photo_populate, NULL/*XXX*/, NULL/*XXX*/),
/* misc fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_URL, "url", "labeledURI"),
+ STRING_PROP (E_CONTACT_HOMEPAGE_URL, "labeledURI"),
/* map nickname to displayName */
- STRING_PROP (E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "displayName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouseName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_NOTE, "note", "note"),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_ANNIVERSARY, "anniversary", "anniversary", anniversary_populate, anniversary_ber, anniversary_compare),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_BIRTH_DATE, "birth_date", "birthDate", birthday_populate, birthday_ber, birthday_compare),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"),
-
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "fileAs"),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_CATEGORIES, "categories", "category", category_populate, category_ber, category_compare),
-
- STRING_PROP (E_CARD_SIMPLE_FIELD_CALURI, "caluri", "calCalURI"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_FBURL, "fburl", "calFBURL"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ICSCALENDAR, "icscalendar", "icsCalendar"),
-
-/* E_CARD_SIMPLE_FIELD_NAME_OR_ORG, */
-
+ STRING_PROP (E_CONTACT_NICKNAME, "displayName"),
+ E_STRING_PROP (E_CONTACT_SPOUSE, "spouseName"),
+ E_STRING_PROP (E_CONTACT_NOTE, "note"),
+ E_COMPLEX_PROP (E_CONTACT_ANNIVERSARY, "anniversary", anniversary_populate, anniversary_ber, anniversary_compare),
+ E_COMPLEX_PROP (E_CONTACT_BIRTH_DATE, "birthDate", birthday_populate, birthday_ber, birthday_compare),
+ E_STRING_PROP (E_CONTACT_MAILER, "mailer"),
+
+ E_STRING_PROP (E_CONTACT_FILE_AS, "fileAs"),
+#if notyet
+ E_COMPLEX_PROP (E_CONTACT_CATEGORIES, "category", category_populate, category_ber, category_compare),
+
+ STRING_PROP (E_CONTACT_CALURI, "calCalURI"),
+ STRING_PROP (E_CONTACT_FBURL, "calFBURL"),
+ STRING_PROP (E_CONTACT_ICSCALENDAR, "icsCalendar"),
+#endif
#undef E_STRING_PROP
#undef STRING_PROP
@@ -285,6 +281,7 @@ struct prop_info {
static int num_prop_infos = sizeof(prop_info) / sizeof(prop_info[0]);
+#if 0
static void
remove_view (int msgid, LDAPOp *op, PASBookView *view)
{
@@ -321,7 +318,6 @@ view_destroy(gpointer data, GObject *where_object_was)
/* free up the view structure */
g_free (view->search);
- g_object_unref (view->card_sexp);
g_free (view);
/* and remove it from our list */
@@ -349,6 +345,7 @@ view_destroy(gpointer data, GObject *where_object_was)
g_object_unref (iter);
}
+#endif
static void
book_view_notify_status (PASBookView *view, const char *status)
@@ -361,6 +358,7 @@ book_view_notify_status (PASBookView *view, const char *status)
static PASBookView*
find_book_view (PASBackendLDAP *bl)
{
+#if 0
EIterator *iter = e_list_get_iterator (bl->priv->book_views);
PASBookView *rv = NULL;
@@ -374,6 +372,7 @@ find_book_view (PASBackendLDAP *bl)
g_object_unref (iter);
return rv;
+#endif
}
static void
@@ -381,21 +380,21 @@ add_to_supported_fields (PASBackendLDAP *bl, char **attrs, GHashTable *attr_hash
{
int i;
for (i = 0; attrs[i]; i ++) {
- char *query_prop = g_hash_table_lookup (attr_hash, attrs[i]);
+ char *query_prop = g_hash_table_lookup (attr_hash, g_strdup (attrs[i]));
if (query_prop) {
- e_list_append (bl->priv->supported_fields, query_prop);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup (query_prop));
/* handle the list attributes here */
if (!strcmp (query_prop, "email")) {
- e_list_append (bl->priv->supported_fields, "email_2");
- e_list_append (bl->priv->supported_fields, "email_3");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_2"));
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_3"));
}
else if (!strcmp (query_prop, "business_phone")) {
- e_list_append (bl->priv->supported_fields, "business_phone_2");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("business_phone_2"));
}
else if (!strcmp (query_prop, "home_phone")) {
- e_list_append (bl->priv->supported_fields, "home_phone_2");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("home_phone_2"));
}
}
}
@@ -408,7 +407,7 @@ add_oc_attributes_to_supported_fields (PASBackendLDAP *bl, LDAPObjectClass *oc)
GHashTable *attr_hash = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < num_prop_infos; i ++)
- g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, prop_info[i].query_prop);
+ g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, (char*)e_contact_field_name (prop_info[i].field_id));
if (oc->oc_at_oids_must)
add_to_supported_fields (bl, oc->oc_at_oids_must, attr_hash);
@@ -591,22 +590,21 @@ query_ldap_root_dse (PASBackendLDAP *bl)
values = ldap_get_values (ldap, resp, "supportedSASLMechanisms");
if (values) {
char *auth_method;
- if (bl->priv->supported_auth_methods)
- g_object_unref (bl->priv->supported_auth_methods);
- bl->priv->supported_auth_methods = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
+ if (bl->priv->supported_auth_methods) {
+ g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_auth_methods);
+ }
+ bl->priv->supported_auth_methods = NULL;
auth_method = g_strdup_printf ("ldap/simple-binddn|%s", _("Using Distinguished Name (DN)"));
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method);
auth_method = g_strdup_printf ("ldap/simple-email|%s", _("Using Email Address"));
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
for (i = 0; values[i]; i++) {
auth_method = g_strdup_printf ("sasl/%s|%s", values[i], values[i]);
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
g_message ("supported SASL mechanism: %s", values[i]);
}
ldap_value_free (values);
@@ -633,7 +631,7 @@ query_ldap_root_dse (PASBackendLDAP *bl)
return LDAP_SUCCESS;
}
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_ldap_connect (PASBackendLDAP *bl)
{
PASBackendLDAPPrivate *blpriv = bl->priv;
@@ -667,7 +665,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
g_message ("TLS not available (fatal version), v3 protocol could not be established (ldap_error 0x%02x)", ldap_error);
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
- return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable;
+ return GNOME_Evolution_Addressbook_TLSNotAvailable;
}
if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) {
@@ -681,7 +679,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
g_message ("TLS not available (fatal version), (ldap_error 0x%02x)", ldap_error);
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
- return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable;
+ return GNOME_Evolution_Addressbook_TLSNotAvailable;
}
else {
g_message ("TLS not available (ldap_error 0x%02x)", ldap_error);
@@ -700,7 +698,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
if (ldap_error == LDAP_SERVER_DOWN) {
/* we only want this to be fatal if the server is down. */
g_warning ("failed to bind anonymously while connecting (ldap_error 0x%02x)", ldap_error);
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
}
ldap_error = query_ldap_root_dse (bl);
@@ -722,7 +720,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
check_schema_support (bl);
pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE);
- return GNOME_Evolution_Addressbook_BookListener_Success;
+ return GNOME_Evolution_Addressbook_Success;
}
else
g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error);
@@ -734,7 +732,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
blpriv->ldap_port,
blpriv->ldap_rootdn ? blpriv->ldap_rootdn : "");
blpriv->connected = FALSE;
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
}
static gboolean
@@ -742,14 +740,14 @@ pas_backend_ldap_reconnect (PASBackendLDAP *bl, PASBookView *book_view, int ldap
{
/* we need to reconnect if we were previously connected */
if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) {
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
+ GNOME_Evolution_Addressbook_CallStatus status;
int ldap_error = LDAP_SUCCESS;
book_view_notify_status (book_view, _("Reconnecting to LDAP server..."));
status = pas_backend_ldap_connect (bl);
- if (status != GNOME_Evolution_Addressbook_BookListener_Success) {
+ if (status != GNOME_Evolution_Addressbook_Success) {
book_view_notify_status (book_view, "");
return FALSE;
}
@@ -836,27 +834,27 @@ static int
ldap_error_to_response (int ldap_error)
{
if (ldap_error == LDAP_SUCCESS)
- return GNOME_Evolution_Addressbook_BookListener_Success;
+ return GNOME_Evolution_Addressbook_Success;
else if (LDAP_NAME_ERROR (ldap_error))
- return GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ return GNOME_Evolution_Addressbook_ContactNotFound;
else if (ldap_error == LDAP_INSUFFICIENT_ACCESS)
- return GNOME_Evolution_Addressbook_BookListener_PermissionDenied;
+ return GNOME_Evolution_Addressbook_PermissionDenied;
else if (ldap_error == LDAP_SERVER_DOWN)
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
else if (ldap_error == LDAP_ALREADY_EXISTS)
- return GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists;
+ return GNOME_Evolution_Addressbook_ContactIdAlreadyExists;
else
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
static char *
-create_dn_from_ecard (ECardSimple *card, const char *root_dn)
+create_dn_from_contact (EContact *contact, const char *root_dn)
{
char *cn, *cn_part = NULL;
char *dn;
- cn = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_FULL_NAME);
+ cn = e_contact_get (contact, E_CONTACT_FULL_NAME);
if (cn) {
if (strchr (cn, ',')) {
/* need to escape commas */
@@ -921,7 +919,7 @@ free_mods (GPtrArray *mods)
}
static GPtrArray*
-build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *new, gboolean *new_dn_needed)
+build_mods_from_contacts (PASBackendLDAP *bl, EContact *current, EContact *new, gboolean *new_dn_needed)
{
gboolean adding = (current == NULL);
GPtrArray *result = g_ptr_array_new();
@@ -946,12 +944,12 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
if (prop_info[i].prop_type & PROP_EVOLVE && !bl->priv->evolutionPersonSupported)
continue;
- /* get the value for the new card, and compare it to
- the value in the current card to see if we should
+ /* get the value for the new contact, and compare it to
+ the value in the current contact to see if we should
update it -- if adding is TRUE, short circuit the
check. */
if (prop_info[i].prop_type & PROP_TYPE_STRING) {
- new_prop = e_card_simple_get (new, prop_info[i].field_id);
+ new_prop = e_contact_get (new, prop_info[i].field_id);
new_prop_present = (new_prop != NULL);
}
else {
@@ -962,7 +960,7 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
/* need to set INCLUDE to true if the field needs to
show up in the ldap modify request */
if (adding) {
- /* if we're creating a new card, include it if the
+ /* if we're creating a new contact, include it if the
field is there at all */
if (prop_info[i].prop_type & PROP_TYPE_STRING)
include = (new_prop_present && *new_prop); /* empty strings cause problems */
@@ -970,13 +968,13 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
include = new_prop_present;
}
else {
- /* if we're modifying an existing card,
+ /* if we're modifying an existing contact,
include it if the current field value is
different than the new one, if it didn't
exist previously, or if it's been
removed. */
if (prop_info[i].prop_type & PROP_TYPE_STRING) {
- current_prop = e_card_simple_get (current, prop_info[i].field_id);
+ current_prop = e_contact_get (current, prop_info[i].field_id);
current_prop_present = (current_prop != NULL);
if (new_prop && current_prop)
@@ -1112,23 +1110,24 @@ add_objectclass_mod (PASBackendLDAP *bl, GPtrArray *mod_array, GList *existing_o
typedef struct {
LDAPOp op;
char *dn;
- ECardSimple *new_card;
+ EContact *new_contact;
} LDAPCreateOp;
static void
-create_card_handler (LDAPOp *op, LDAPMessage *res)
+create_contact_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPCreateOp *create_op = (LDAPCreateOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
LDAP *ldap = bl->priv->ldap;
+ EContact *contact;
int ldap_error;
int response;
if (LDAP_RES_ADD != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to create_card_handler", ldap_msgtype (res));
+ g_warning ("incorrect msg type %d passed to create_contact_handler", ldap_msgtype (res));
pas_book_respond_create (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- create_op->dn);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1136,75 +1135,34 @@ create_card_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was created, let's let the views know about it */
- EIterator *iter;
-
- iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- gboolean match;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
- char *new_vcard;
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- new_vcard = e_card_simple_get_vcard_assume_utf8 (create_op->new_card);
-
- match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- new_vcard);
- if (match) {
- pas_book_view_notify_add_1 (view->book_view,
- new_vcard);
- }
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
- g_free (new_vcard);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (ldap, "create_card");
- }
-
- if (op->view)
- pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
/* and lastly respond */
response = ldap_error_to_response (ldap_error);
pas_book_respond_create (op->book,
response,
- create_op->dn);
+ create_op->new_contact);
ldap_op_finished (op);
}
static void
-create_card_dtor (LDAPOp *op)
+create_contact_dtor (LDAPOp *op)
{
LDAPCreateOp *create_op = (LDAPCreateOp*)op;
g_free (create_op->dn);
- g_object_unref (create_op->new_card);
+ g_object_unref (create_op->new_contact);
g_free (create_op);
}
static void
-pas_backend_ldap_process_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+pas_backend_ldap_process_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
PASBookView *book_view;
- int create_card_msgid;
- ECard *new_ecard;
+ int create_contact_msgid;
int response;
int err;
GPtrArray *mod_array;
@@ -1213,18 +1171,17 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
book_view = find_book_view (bl);
- printf ("vcard = %s\n", req->vcard);
+ printf ("vcard = %s\n", vcard);
- new_ecard = e_card_new (req->vcard);
- create_op->new_card = e_card_simple_new (new_ecard);
+ create_op->new_contact = e_contact_new_from_vcard (vcard);
- create_op->dn = create_dn_from_ecard (create_op->new_card, bl->priv->ldap_rootdn);
- e_card_simple_set_id (create_op->new_card, create_op->dn); /* for the notification code below */
+ create_op->dn = create_dn_from_contact (create_op->new_contact, bl->priv->ldap_rootdn);
+ e_contact_set (create_op->new_contact, E_CONTACT_UID, create_op->dn);
ldap = bl->priv->ldap;
/* build our mods */
- mod_array = build_mods_from_ecards (bl, NULL, create_op->new_card, NULL);
+ mod_array = build_mods_from_contacts (bl, NULL, create_op->new_contact, NULL);
#if 0
if (!mod_array) {
@@ -1232,10 +1189,10 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
UnsupportedAttribute back */
pas_book_respond_create (book,
GNOME_Evolution_Addressbook_BookListener_UnsupportedField,
- create_op->dn);
+ NULL);
g_free (create_op->dn);
- g_object_unref (create_op->new_card);
+ g_object_unref (create_op->new_contact);
g_free (create_op);
return;
}
@@ -1288,10 +1245,10 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
ldap_mods = (LDAPMod**)mod_array->pdata;
do {
- book_view_notify_status (book_view, _("Adding card to LDAP server..."));
+ book_view_notify_status (book_view, _("Adding contact to LDAP server..."));
err = ldap_add_ext (ldap, create_op->dn, ldap_mods,
- NULL, NULL, &create_card_msgid);
+ NULL, NULL, &create_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, err));
@@ -1302,15 +1259,15 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
response = ldap_error_to_response (err);
pas_book_respond_create (create_op->op.book,
response,
- create_op->dn);
- create_card_dtor ((LDAPOp*)create_op);
+ NULL);
+ create_contact_dtor ((LDAPOp*)create_op);
return;
}
else {
g_print ("ldap_add_ext returned %d\n", err);
ldap_op_add ((LDAPOp*)create_op, backend, book,
- book_view, create_card_msgid,
- create_card_handler, create_card_dtor);
+ book_view, create_contact_msgid,
+ create_contact_handler, create_contact_dtor);
}
}
@@ -1321,16 +1278,18 @@ typedef struct {
} LDAPRemoveOp;
static void
-remove_card_handler (LDAPOp *op, LDAPMessage *res)
+remove_contact_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
int ldap_error;
+ GList *ids = NULL;
if (LDAP_RES_DELETE != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to remove_card_handler", ldap_msgtype (res));
- pas_book_respond_remove (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ g_warning ("incorrect msg type %d passed to remove_contact_handler", ldap_msgtype (res));
+ pas_book_respond_remove_contacts (op->book,
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1338,39 +1297,15 @@ remove_card_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (bl->priv->ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was removed, let's let the views know about it */
- EIterator *iter = e_list_get_iterator (bl->priv->book_views);
-
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- 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);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (bl->priv->ldap, "remove_card");
- }
-
- pas_book_respond_remove (remove_op->op.book,
- ldap_error_to_response (ldap_error));
-
- if (op->view)
- pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ ids = g_list_append (ids, remove_op->id);
+ pas_book_respond_remove_contacts (remove_op->op.book,
+ ldap_error_to_response (ldap_error),
+ ids);
+ g_list_free (ids);
}
static void
-remove_card_dtor (LDAPOp *op)
+remove_contact_dtor (LDAPOp *op)
{
LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
@@ -1379,9 +1314,9 @@ remove_card_dtor (LDAPOp *op)
}
static void
-pas_backend_ldap_process_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+pas_backend_ldap_process_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *ids)
{
LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1396,10 +1331,10 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
** 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);
+ remove_op->id = g_strdup (ids->data);
do {
- book_view_notify_status (book_view, _("Removing card from LDAP server..."));
+ book_view_notify_status (book_view, _("Removing contact from LDAP server..."));
ldap_error = ldap_delete_ext (bl->priv->ldap,
remove_op->id,
@@ -1407,16 +1342,17 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error != LDAP_SUCCESS) {
- pas_book_respond_remove (remove_op->op.book,
- ldap_error_to_response (ldap_error));
- remove_card_dtor ((LDAPOp*)remove_op);
+ pas_book_respond_remove_contacts (remove_op->op.book,
+ ldap_error_to_response (ldap_error),
+ NULL);
+ remove_contact_dtor ((LDAPOp*)remove_op);
return;
}
else {
g_print ("ldap_delete_ext returned %d\n", ldap_error);
ldap_op_add ((LDAPOp*)remove_op, backend, book,
book_view, remove_msgid,
- remove_card_handler, remove_card_dtor);
+ remove_contact_handler, remove_contact_dtor);
}
}
@@ -1427,23 +1363,21 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
** The modification request is actually composed of 2 separate
** requests. Since we need to get a list of theexisting objectclasses
** used by the ldap server for the entry, and since the UI only sends
-** us the current card, we need to query the ldap server for the
-** existing card.
+** us the current contact, we need to query the ldap server for the
+** existing contact.
**
*/
typedef struct {
LDAPOp op;
- const char *id; /* the id of the card we're modifying */
- char *current_vcard; /* current in the LDAP db */
- ECardSimple *current_card;
- char *vcard; /* the VCard we want to store */
- ECardSimple *card;
+ const char *id; /* the id of the contact we're modifying */
+ EContact *current_contact;
+ EContact *contact;
GList *existing_objectclasses;
} LDAPModifyOp;
static void
-modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
+modify_contact_modify_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
@@ -1451,9 +1385,10 @@ modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
int ldap_error;
if (LDAP_RES_MODIFY != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to modify_card_handler", ldap_msgtype (res));
+ g_warning ("incorrect msg type %d passed to modify_contact_handler", ldap_msgtype (res));
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1461,48 +1396,15 @@ modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was modified, let's let the views know about it */
- EIterator *iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- gboolean old_match, new_match;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- old_match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- modify_op->current_vcard);
- new_match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- modify_op->vcard);
- if (old_match && new_match)
- pas_book_view_notify_change_1 (view->book_view, modify_op->vcard);
- 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_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);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (ldap, "ldap_modify_s");
- }
-
/* and lastly respond */
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ modify_op->contact);
ldap_op_finished (op);
}
static void
-modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
+modify_contact_search_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
@@ -1520,14 +1422,14 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
if (!e) {
g_warning ("uh, this shouldn't happen");
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
- modify_op->current_card = build_card_from_entry (ldap, e,
- &modify_op->existing_objectclasses);
- modify_op->current_vcard = e_card_simple_get_vcard_assume_utf8 (modify_op->current_card);
+ modify_op->current_contact = build_contact_from_entry (ldap, e,
+ &modify_op->existing_objectclasses);
}
else if (msg_type == LDAP_RES_SEARCH_RESULT) {
int ldap_error;
@@ -1535,7 +1437,7 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
GPtrArray *mod_array;
gboolean differences;
gboolean need_new_dn;
- int modify_card_msgid;
+ int modify_contact_msgid;
/* grab the result code, and set up the actual modify
if it was successful */
@@ -1545,13 +1447,14 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
if (ldap_error != LDAP_SUCCESS) {
/* more here i'm sure */
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ NULL);
ldap_op_finished (op);
return;
}
/* build our mods */
- mod_array = build_mods_from_ecards (bl, modify_op->current_card, modify_op->card, &need_new_dn);
+ mod_array = build_mods_from_contacts (bl, modify_op->current_contact, modify_op->contact, &need_new_dn);
differences = mod_array->len > 0;
if (differences) {
@@ -1569,17 +1472,18 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
/* actually perform the ldap modify */
ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods,
- NULL, NULL, &modify_card_msgid);
+ NULL, NULL, &modify_contact_msgid);
if (ldap_error == LDAP_SUCCESS) {
- op->handler = modify_card_modify_handler;
+ op->handler = modify_contact_modify_handler;
ldap_op_change_id ((LDAPOp*)modify_op,
- modify_card_msgid);
+ modify_contact_msgid);
}
else {
g_warning ("ldap_modify_ext returned %d\n", ldap_error);
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1591,84 +1495,80 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
else {
g_warning ("unhandled result type %d returned", msg_type);
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
}
}
static void
-modify_card_dtor (LDAPOp *op)
+modify_contact_dtor (LDAPOp *op)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
g_list_foreach (modify_op->existing_objectclasses, (GFunc)g_free, NULL);
g_list_free (modify_op->existing_objectclasses);
- g_free (modify_op->current_vcard);
- if (modify_op->current_card)
- g_object_unref (modify_op->current_card);
- g_free (modify_op->vcard);
- if (modify_op->card)
- g_object_unref (modify_op->card);
+ if (modify_op->current_contact)
+ g_object_unref (modify_op->current_contact);
+ if (modify_op->contact)
+ g_object_unref (modify_op->contact);
g_free (modify_op);
}
static void
-pas_backend_ldap_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+pas_backend_ldap_process_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- ECard *new_ecard;
int ldap_error;
LDAP *ldap;
- int modify_card_msgid;
+ int modify_contact_msgid;
PASBookView *book_view;
book_view = find_book_view (bl);
- modify_op->vcard = g_strdup (req->vcard);
- new_ecard = e_card_new (modify_op->vcard);
- modify_op->card = e_card_simple_new (new_ecard);
- g_object_unref (new_ecard);
- modify_op->id = e_card_simple_get_id(modify_op->card);
+ modify_op->contact = e_contact_new_from_vcard (vcard);
+ modify_op->id = e_contact_get_const (modify_op->contact, E_CONTACT_UID);
ldap = bl->priv->ldap;
- book_view_notify_status (book_view, _("Modifying card from LDAP server..."));
+ book_view_notify_status (book_view, _("Modifying contact from LDAP server..."));
do {
- book_view_notify_status (book_view, _("Modifying card from LDAP server..."));
+ book_view_notify_status (book_view, _("Modifying contact from LDAP server..."));
ldap_error = ldap_search_ext (ldap, modify_op->id,
LDAP_SCOPE_BASE,
"(objectclass=*)",
NULL, 0, NULL, NULL,
NULL, /* XXX timeout */
- 1, &modify_card_msgid);
+ 1, &modify_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error == LDAP_SUCCESS) {
ldap_op_add ((LDAPOp*)modify_op, backend, book,
- book_view, modify_card_msgid,
- modify_card_search_handler, modify_card_dtor);
+ book_view, modify_contact_msgid,
+ modify_contact_search_handler, modify_contact_dtor);
}
else {
g_warning ("ldap_search_ext returned %d\n", ldap_error);
pas_book_respond_modify (book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
- modify_card_dtor ((LDAPOp*)modify_op);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
+ modify_contact_dtor ((LDAPOp*)modify_op);
}
}
typedef struct {
LDAPOp op;
-} LDAPGetVCardOp;
+} LDAPGetContactOp;
static void
-get_vcard_handler (LDAPOp *op, LDAPMessage *res)
+get_contact_handler (LDAPOp *op, LDAPMessage *res)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
int msg_type;
@@ -1679,37 +1579,37 @@ get_vcard_handler (LDAPOp *op, LDAPMessage *res)
msg_type = ldap_msgtype (res);
if (msg_type == LDAP_RES_SEARCH_ENTRY) {
LDAPMessage *e = ldap_first_entry(bl->priv->ldap, res);
- ECardSimple *simple;
+ EContact *contact;
char *vcard;
if (!e) {
g_warning ("uh, this shouldn't happen");
- pas_book_respond_get_vcard (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- "");
+ pas_book_respond_get_contact (op->book,
+ GNOME_Evolution_Addressbook_OtherError,
+ "");
ldap_op_finished (op);
return;
}
- simple = build_card_from_entry (bl->priv->ldap, e, NULL);
- vcard = e_card_simple_get_vcard_assume_utf8 (simple);
- pas_book_respond_get_vcard (op->book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- vcard);
+ contact = build_contact_from_entry (bl->priv->ldap, e, NULL);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ pas_book_respond_get_contact (op->book,
+ GNOME_Evolution_Addressbook_Success,
+ vcard);
g_free (vcard);
- g_object_unref (simple);
+ g_object_unref (contact);
ldap_op_finished (op);
}
else if (msg_type == LDAP_RES_SEARCH_RESULT) {
int ldap_error;
ldap_parse_result (bl->priv->ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- pas_book_respond_get_vcard (op->book, ldap_error_to_response (ldap_error), "");
+ pas_book_respond_get_contact (op->book, ldap_error_to_response (ldap_error), "");
ldap_op_finished (op);
}
else {
g_warning ("unhandled result type %d returned", msg_type);
- pas_book_respond_get_vcard (op->book, GNOME_Evolution_Addressbook_BookListener_OtherError,
+ pas_book_respond_get_contact (op->book, GNOME_Evolution_Addressbook_OtherError,
"");
ldap_op_finished (op);
}
@@ -1717,254 +1617,75 @@ get_vcard_handler (LDAPOp *op, LDAPMessage *res)
}
static void
-get_vcard_dtor (LDAPOp *op)
+get_contact_dtor (LDAPOp *op)
{
- LDAPGetVCardOp *get_vcard_op = (LDAPGetVCardOp*)op;
+ LDAPGetContactOp *get_contact_op = (LDAPGetContactOp*)op;
- g_free (get_vcard_op);
+ g_free (get_contact_op);
}
static void
-pas_backend_ldap_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_ldap_process_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
{
- LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1);
+ LDAPGetContactOp *get_contact_op = g_new0 (LDAPGetContactOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
LDAP *ldap = bl->priv->ldap;
- int get_vcard_msgid;
+ int get_contact_msgid;
PASBookView *book_view;
int ldap_error;
book_view = find_book_view (bl);
do {
- ldap_error = ldap_search_ext (ldap, req->id,
+ ldap_error = ldap_search_ext (ldap, id,
LDAP_SCOPE_BASE,
"(objectclass=*)",
NULL, 0, NULL, NULL,
NULL, /* XXX timeout */
- 1, &get_vcard_msgid);
+ 1, &get_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error == LDAP_SUCCESS) {
- ldap_op_add ((LDAPOp*)get_vcard_op, backend, book,
- book_view, get_vcard_msgid,
- get_vcard_handler, get_vcard_dtor);
+ ldap_op_add ((LDAPOp*)get_contact_op, backend, book,
+ book_view, get_contact_msgid,
+ get_contact_handler, get_contact_dtor);
}
else {
- pas_book_respond_get_vcard (book,
+ pas_book_respond_get_contact (book,
ldap_error_to_response (ldap_error),
"");
- get_vcard_dtor ((LDAPOp*)get_vcard_op);
+ get_contact_dtor ((LDAPOp*)get_contact_op);
}
}
-typedef struct {
- LDAPOp op;
- PASBackendLDAPCursorPrivate *cursor_data;
- gboolean responded; /* if FALSE, we need to free cursor_data in the dtor */
-} LDAPGetCursorOp;
-
-static long
-get_length(PASCardCursor *cursor, gpointer data)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
-
- return cursor_data->num_elements;
-}
-
-static char *
-get_nth(PASCardCursor *cursor, long n, gpointer data)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
-
- g_return_val_if_fail (n < cursor_data->num_elements, NULL);
-
- return (char*)g_list_nth (cursor_data->elements, n);
-}
-
-static void
-cursor_destroy(gpointer data, GObject *where_object_was)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
- if (cursor_data->book) {
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("cursor_destroy: Exception unreffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
- }
-
- /* free the ldap specific cursor information */
- g_list_foreach (cursor_data->elements, (GFunc)g_free, NULL);
- g_list_free (cursor_data->elements);
-
- g_free(cursor_data);
-}
-
-static void
-get_cursor_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- LDAP *ldap = bl->priv->ldap;
- int msg_type;
-
- msg_type = ldap_msgtype (res);
- if (msg_type == LDAP_RES_SEARCH_ENTRY) {
- LDAPMessage *e;
-
- e = ldap_first_entry (ldap, res);
- while (e) {
- ECardSimple *simple;
-
- simple = build_card_from_entry (ldap, e, NULL);
- if (simple) {
- char *vcard = e_card_simple_get_vcard_assume_utf8 (simple);
- cursor_op->cursor_data->num_elements ++;
- cursor_op->cursor_data->elements = g_list_prepend (cursor_op->cursor_data->elements,
- vcard);
- g_object_unref (simple);
- }
- }
- }
- else if (msg_type == LDAP_RES_SEARCH_RESULT) {
- PASCardCursor *cursor = CORBA_OBJECT_NIL;
- int ldap_error;
- ldap_parse_result (bl->priv->ldap, res, &ldap_error,
- NULL, NULL, NULL, NULL, 0);
-
- if (ldap_error == LDAP_SUCCESS) {
- cursor = pas_card_cursor_new(get_length,
- get_nth,
- cursor_op->cursor_data);
-
- g_object_weak_ref (G_OBJECT (cursor), cursor_destroy, cursor_op->cursor_data);
-
- cursor_op->responded = TRUE;
- }
-
- pas_book_respond_get_cursor (cursor_op->cursor_data->book,
- ldap_error_to_response (ldap_error),
- cursor);
-
- ldap_op_finished (op);
- }
- else {
- g_warning ("unhandled result type %d returned", msg_type);
- pas_book_respond_get_cursor (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- CORBA_OBJECT_NIL);
- ldap_op_finished (op);
- }
-}
-
-static void
-get_cursor_dtor (LDAPOp *op)
-{
- LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op;
-
- if (!cursor_op->responded) {
- cursor_destroy (cursor_op->cursor_data, NULL);
- }
-
- g_free (op);
-}
-
-static void
-pas_backend_ldap_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- LDAP *ldap = bl->priv->ldap;
- int ldap_error;
- int get_cursor_msgid;
- LDAPGetCursorOp *cursor_op;
- PASBookView *book_view;
-
- book_view = find_book_view (bl);
-
- cursor_op = g_new0 (LDAPGetCursorOp, 1);
- cursor_op->cursor_data = g_new0 (PASBackendLDAPCursorPrivate, 1);
-
- do {
- ldap_error = ldap_search_ext (ldap,
- bl->priv->ldap_rootdn,
- bl->priv->ldap_scope,
- "(objectclass=*)",
- NULL, 0,
- NULL, NULL, NULL, /* timeout */
- 0, &get_cursor_msgid);
- } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
-
- if (ldap_error == LDAP_SUCCESS) {
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev);
-
- cursor_op->cursor_data->backend = backend;
- cursor_op->cursor_data->book = book;
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("pas_backend_ldap_process_get_cursor: Exception reffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
-
-
- ldap_op_add ((LDAPOp*)cursor_op, backend, book,
- NULL, get_cursor_msgid, get_cursor_handler, get_cursor_dtor);
- }
- else {
- pas_book_respond_get_cursor (book,
- ldap_error_to_response (ldap_error),
- CORBA_OBJECT_NIL);
- get_cursor_dtor ((LDAPOp*)cursor_op);
- }
-}
+static EContactField email_ids[3] = {
+ E_CONTACT_EMAIL_1,
+ E_CONTACT_EMAIL_2,
+ E_CONTACT_EMAIL_3
+};
-
/* List property functions */
static void
-email_populate(ECardSimple *card, char **values)
+email_populate(EContact *contact, char **values)
{
int i;
-
- for (i = 0; values[i] && i < 3; i ++) {
- e_card_simple_set_email (card, i, values[i]);
- }
+ for (i = 0; values[i] && i < 3; i ++)
+ e_contact_set (contact, email_ids[i], values[i]);
}
struct berval**
-email_ber(ECardSimple *card)
+email_ber(EContact *contact)
{
struct berval** result;
const char *emails[3];
- int i, j, num;
+ int i, j, num = 0;
- num = 0;
for (i = 0; i < 3; i ++) {
- emails[i] = e_card_simple_get_email (card, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
+ emails[i] = e_contact_get (contact, email_ids[i]);
if (emails[i])
num++;
}
@@ -1991,15 +1712,15 @@ email_ber(ECardSimple *card)
}
static gboolean
-email_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+email_compare (EContact *contact1, EContact *contact2)
{
const char *email1, *email2;
int i;
for (i = 0; i < 3; i ++) {
gboolean equal;
- email1 = e_card_simple_get_email (ecard1, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
- email2 = e_card_simple_get_email (ecard2, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
+ email1 = e_contact_get_const (contact1, email_ids[i]);
+ email2 = e_contact_get_const (contact2, email_ids[i]);
if (email1 && email2)
equal = !strcmp (email1, email2);
@@ -2014,26 +1735,26 @@ email_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-homephone_populate(ECardSimple *card, char **values)
+homephone_populate(EContact *contact, char **values)
{
if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME, values[0]);
+ e_contact_set (contact, E_CONTACT_PHONE_HOME, values[0]);
if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2, values[1]);
+ e_contact_set (contact, E_CONTACT_PHONE_HOME_2, values[1]);
}
}
struct berval**
-homephone_ber(ECardSimple *card)
+homephone_ber(EContact *contact)
{
struct berval** result;
const char *homephones[3];
int i, j, num;
num = 0;
- if ((homephones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME)))
+ if ((homephones[0] = e_contact_get (contact, E_CONTACT_PHONE_HOME)))
num++;
- if ((homephones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2)))
+ if ((homephones[1] = e_contact_get (contact, E_CONTACT_PHONE_HOME_2)))
num++;
if (num == 0)
@@ -2058,16 +1779,16 @@ homephone_ber(ECardSimple *card)
}
static gboolean
-homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+homephone_compare (EContact *contact1, EContact *contact2)
{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_HOME, E_CARD_SIMPLE_FIELD_PHONE_HOME_2 };
+ int phone_ids[2] = { E_CONTACT_PHONE_HOME, E_CONTACT_PHONE_HOME_2 };
const char *phone1, *phone2;
int i;
for (i = 0; i < 2; i ++) {
gboolean equal;
- phone1 = e_card_simple_get (ecard1, phone_ids[i]);
- phone2 = e_card_simple_get (ecard2, phone_ids[i]);
+ phone1 = e_contact_get (contact1, phone_ids[i]);
+ phone2 = e_contact_get (contact2, phone_ids[i]);
if (phone1 && phone2)
equal = !strcmp (phone1, phone2);
@@ -2082,26 +1803,26 @@ homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-business_populate(ECardSimple *card, char **values)
+business_populate(EContact *contact, char **values)
{
if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, values[0]);
+ e_contact_set (contact, E_CONTACT_PHONE_BUSINESS, values[0]);
if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, values[1]);
+ e_contact_set (contact, E_CONTACT_PHONE_BUSINESS_2, values[1]);
}
}
struct berval**
-business_ber(ECardSimple *card)
+business_ber(EContact *contact)
{
struct berval** result;
const char *business_phones[3];
int i, j, num;
num = 0;
- if ((business_phones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS)))
+ if ((business_phones[0] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS)))
num++;
- if ((business_phones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2)))
+ if ((business_phones[1] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS_2)))
num++;
if (num == 0)
@@ -2126,16 +1847,16 @@ business_ber(ECardSimple *card)
}
static gboolean
-business_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+business_compare (EContact *contact1, EContact *contact2)
{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2 };
+ int phone_ids[2] = { E_CONTACT_PHONE_BUSINESS, E_CONTACT_PHONE_BUSINESS_2 };
const char *phone1, *phone2;
int i;
for (i = 0; i < 2; i ++) {
gboolean equal;
- phone1 = e_card_simple_get (ecard1, phone_ids[i]);
- phone2 = e_card_simple_get (ecard2, phone_ids[i]);
+ phone1 = e_contact_get (contact1, phone_ids[i]);
+ phone2 = e_contact_get (contact2, phone_ids[i]);
if (phone1 && phone2)
equal = !strcmp (phone1, phone2);
@@ -2150,30 +1871,26 @@ business_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-anniversary_populate (ECardSimple *card, char **values)
+anniversary_populate (EContact *contact, char **values)
{
if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- g_object_set (card->card,
- "anniversary", &dt,
- NULL);
+ EContactDate *dt = e_contact_date_from_string (values[0]);
+ e_contact_set (contact, E_CONTACT_ANNIVERSARY, &dt);
}
}
struct berval**
-anniversary_ber (ECardSimple *card)
+anniversary_ber (EContact *contact)
{
- ECardDate *dt;
+ EContactDate *dt;
struct berval** result = NULL;
- g_object_get (card->card,
- "anniversary", &dt,
- NULL);
+ dt = e_contact_get (contact, E_CONTACT_ANNIVERSARY);
if (dt) {
char *anniversary;
- anniversary = e_card_date_to_string (dt);
+ anniversary = e_contact_date_to_string (dt);
result = g_new (struct berval*, 2);
result[0] = g_new (struct berval, 1);
@@ -2181,29 +1898,31 @@ anniversary_ber (ECardSimple *card)
result[0]->bv_len = strlen (anniversary);
result[1] = NULL;
+
+ e_contact_date_free (dt);
}
return result;
}
static gboolean
-anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+anniversary_compare (EContact *contact1, EContact *contact2)
{
- ECardDate *dt;
+ EContactDate *dt;
char *date1 = NULL, *date2 = NULL;
gboolean equal;
- g_object_get (ecard1->card,
- "anniversary", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
-
- g_object_get (ecard2->card,
- "anniversary", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact1, E_CONTACT_ANNIVERSARY);
+ if (dt) {
+ date1 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
+
+ dt = e_contact_get (contact2, E_CONTACT_ANNIVERSARY);
+ if (dt) {
+ date2 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
if (date1 && date2)
equal = !strcmp (date1, date2);
@@ -2217,30 +1936,26 @@ anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-birthday_populate (ECardSimple *card, char **values)
+birthday_populate (EContact *contact, char **values)
{
if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- g_object_set (card->card,
- "birth_date", &dt,
- NULL);
+ EContactDate *dt = e_contact_date_from_string (values[0]);
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, dt);
+ e_contact_date_free (dt);
}
}
struct berval**
-birthday_ber (ECardSimple *card)
+birthday_ber (EContact *contact)
{
- ECardDate *dt;
+ EContactDate *dt;
struct berval** result = NULL;
- g_object_get (card->card,
- "birth_date", &dt,
- NULL);
-
+ dt = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
if (dt) {
char *birthday;
- birthday = e_card_date_to_string (dt);
+ birthday = e_contact_date_to_string (dt);
result = g_new (struct berval*, 2);
result[0] = g_new (struct berval, 1);
@@ -2248,29 +1963,31 @@ birthday_ber (ECardSimple *card)
result[0]->bv_len = strlen (birthday);
result[1] = NULL;
+
+ e_contact_date_free (dt);
}
return result;
}
static gboolean
-birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+birthday_compare (EContact *contact1, EContact *contact2)
{
- ECardDate *dt;
+ EContactDate *dt;
char *date1 = NULL, *date2 = NULL;
gboolean equal;
- g_object_get (ecard1->card,
- "birth_date", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact1, E_CONTACT_BIRTH_DATE);
+ if (dt) {
+ date1 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
- g_object_get (ecard2->card,
- "birth_date", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact2, E_CONTACT_BIRTH_DATE);
+ if (dt) {
+ date2 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
if (date1 && date2)
equal = !strcmp (date1, date2);
@@ -2284,10 +2001,11 @@ birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-category_populate (ECardSimple *card, char **values)
+category_populate (EContact *contact, char **values)
{
+#if notyet
int i;
- ECard *ecard;
+ EContact *ecard;
EList *categories;
g_object_get (card,
@@ -2309,15 +2027,17 @@ category_populate (ECardSimple *card, char **values)
e_card_simple_sync_card (card);
g_object_unref (ecard);
+#endif
}
struct berval**
-category_ber (ECardSimple *card)
+category_ber (EContact *contact)
{
+#if notyet
struct berval** result = NULL;
EList *categories;
EIterator *iterator;
- ECard *ecard;
+ EContact *ecard;
int i;
g_object_get (card,
@@ -2346,16 +2066,18 @@ category_ber (ECardSimple *card)
g_object_unref (categories);
g_object_unref (ecard);
return result;
+#endif
}
static gboolean
-category_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+category_compare (EContact *contact1, EContact *contact2)
{
+#if notyet
char *categories1, *categories2;
gboolean equal;
- categories1 = e_card_simple_get (ecard1, E_CARD_SIMPLE_FIELD_CATEGORIES);
- categories2 = e_card_simple_get (ecard2, E_CARD_SIMPLE_FIELD_CATEGORIES);
+ categories1 = e_card_simple_get (ecard1, E_CONTACT_CATEGORIES);
+ categories2 = e_card_simple_get (ecard2, E_CONTACT_CATEGORIES);
equal = !strcmp (categories1, categories2);
@@ -2363,6 +2085,19 @@ category_compare (ECardSimple *ecard1, ECardSimple *ecard2)
g_free (categories2);
return equal;
+#endif
+}
+
+static void
+photo_populate (EContact *contact, struct berval **ber_values)
+{
+ if (ber_values && ber_values[0]) {
+ EContactPhoto photo;
+ photo.data = ber_values[0]->bv_val;
+ photo.length = ber_values[0]->bv_len;
+
+ e_contact_set (contact, E_CONTACT_PHOTO, &photo);
+ }
}
typedef struct {
@@ -2670,6 +2405,58 @@ func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
return r;
}
+static ESExpResult *
+func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ PASBackendLDAPSExpData *ldap_data = data;
+ ESExpResult *r;
+
+ if (argc == 1
+ && argv[0]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+
+ if (!strcmp (propname, "x-evolution-any-field")) {
+ int i;
+ int query_length;
+ char *big_query;
+ char *match_str;
+
+ match_str = g_strdup("=*)");
+
+ query_length = 3; /* strlen ("(|") + strlen (")") */
+
+ for (i = 0; i < num_prop_infos; i ++) {
+ query_length += 1 /* strlen ("(") */ + strlen(prop_info[i].ldap_attr) + strlen (match_str);
+ }
+
+ big_query = g_malloc0(query_length + 1);
+ strcat (big_query, "(|");
+ for (i = 0; i < num_prop_infos; i ++) {
+ strcat (big_query, "(");
+ strcat (big_query, prop_info[i].ldap_attr);
+ strcat (big_query, match_str);
+ }
+ strcat (big_query, ")");
+
+ ldap_data->list = g_list_prepend(ldap_data->list, big_query);
+
+ g_free (match_str);
+ }
+ else {
+ char *ldap_attr = query_prop_to_ldap(propname);
+
+ if (ldap_attr)
+ ldap_data->list = g_list_prepend(ldap_data->list,
+ g_strdup_printf("(%s=*)", ldap_attr));
+ }
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
/* 'builtin' functions */
static struct {
char *name;
@@ -2684,10 +2471,11 @@ static struct {
{ "is", func_is, 0 },
{ "beginswith", func_beginswith, 0 },
{ "endswith", func_endswith, 0 },
+ { "exists", func_exists, 0 },
};
static gchar *
-pas_backend_ldap_build_query (PASBackendLDAP *bl, gchar *query)
+pas_backend_ldap_build_query (PASBackendLDAP *bl, const char *query)
{
ESExp *sexp;
ESExpResult *r;
@@ -2743,7 +2531,7 @@ query_prop_to_ldap(gchar *query_prop)
int i;
for (i = 0; i < num_prop_infos; i ++)
- if (!strcmp (query_prop, prop_info[i].query_prop))
+ if (!strcmp (query_prop, e_contact_field_name (prop_info[i].field_id)))
return prop_info[i].ldap_attr;
return NULL;
@@ -2752,31 +2540,22 @@ query_prop_to_ldap(gchar *query_prop)
typedef struct {
LDAPOp op;
- PASBackendLDAPBookView *view;
-
- /* grouping stuff */
- GList *pending_adds; /* the cards we're sending */
- int num_pending_adds; /* the number waiting to be sent */
- int target_pending_adds; /* the cutoff that forces a flush to the client, if it happens before the timeout */
- int num_sent_this_time; /* the number of cards we sent to the client before the most recent timeout */
- int num_sent_last_time; /* the number of cards we sent to the client before the previous timeout */
- glong grouping_time_start;
-
+ PASBookView *view;
+
/* used by search_handler to only send the status messages once */
gboolean notified_receiving_results;
} LDAPSearchOp;
-static ECardSimple *
-build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses)
+static EContact *
+build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses)
{
- ECard *ecard = e_card_new ("");
- ECardSimple *card = e_card_simple_new (ecard);
+ EContact *contact = e_contact_new ();
char *dn;
char *attr;
BerElement *ber = NULL;
dn = ldap_get_dn(ldap, e);
- e_card_simple_set_id (card, dn);
+ e_contact_set (contact, E_CONTACT_UID, dn);
ldap_memfree (dn);
for (attr = ldap_first_attribute (ldap, e, &ber); attr;
@@ -2799,24 +2578,41 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse
break;
}
+ printf ("attr = %s, ", attr);
+ printf ("info = %p\n", info);
+
if (info) {
- values = ldap_get_values (ldap, e, attr);
+ if (info->prop_type & PROP_WRITE_ONLY)
+ continue;
+
+ if (info->prop_type & PROP_TYPE_BINARY) {
+ struct berval **ber_values = ldap_get_values_len (ldap, e, attr);
- if (values) {
- if (info->prop_type & PROP_TYPE_STRING) {
- /* if it's a normal property just set the string */
- if (values[0])
- e_card_simple_set (card, info->field_id, values[0]);
+ if (ber_values) {
+ info->binary_populate_contact_func (contact, ber_values);
+ ldap_value_free_len (ber_values);
}
- else if (info->prop_type & PROP_TYPE_COMPLEX) {
- /* if it's a list call the ecard-populate function,
- which calls g_object_set to set the property */
- info->populate_ecard_func(card,
- values);
+ }
+ else {
+ values = ldap_get_values (ldap, e, attr);
+
+ if (values) {
+ if (info->prop_type & PROP_TYPE_STRING) {
+ printf ("value = %s\n", values[0]);
+ /* if it's a normal property just set the string */
+ if (values[0])
+ e_contact_set (contact, info->field_id, values[0]);
+ }
+ else if (info->prop_type & PROP_TYPE_COMPLEX) {
+ /* if it's a list call the contact-populate function,
+ which calls g_object_set to set the property */
+ info->populate_contact_func(contact,
+ values);
+ }
+
+ ldap_value_free (values);
}
-
- ldap_value_free (values);
}
}
}
@@ -2827,11 +2623,7 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse
if (ber)
ber_free (ber, 0);
- e_card_simple_sync_card (card);
-
- g_object_unref (ecard);
-
- return card;
+ return contact;
}
static gboolean
@@ -2840,10 +2632,7 @@ poll_ldap (PASBackendLDAP *bl)
LDAP *ldap = bl->priv->ldap;
int rc;
LDAPMessage *res;
- GTimeVal cur_time;
- glong cur_millis;
struct timeval timeout;
- EIterator *iter;
if (!bl->priv->active_ops) {
g_warning ("poll_ldap being called for backend with no active operations");
@@ -2880,81 +2669,20 @@ poll_ldap (PASBackendLDAP *bl)
}
}
- g_get_current_time (&cur_time);
- cur_millis = TV_TO_MILLIS (cur_time);
-
- iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView *)e_iterator_get (iter);
- if (view->search_op) {
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
-
- ldap_search_op_timeout (view->search_op, cur_millis);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
- }
- e_iterator_next (iter);
- }
- g_object_unref (iter);
-
return TRUE;
}
static void
-send_pending_adds (LDAPSearchOp *search_op)
-{
- search_op->num_sent_this_time += search_op->num_pending_adds;
- pas_book_view_notify_add (search_op->op.view, search_op->pending_adds);
- g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL);
- g_list_free (search_op->pending_adds);
- search_op->pending_adds = NULL;
- search_op->num_pending_adds = 0;
-}
-
-static void
-ldap_search_op_timeout (LDAPOp *op, glong cur_millis)
-{
- LDAPSearchOp *search_op = (LDAPSearchOp*)op;
-
- if (cur_millis - search_op->grouping_time_start > GROUPING_MINIMUM_WAIT) {
-
- if (search_op->num_pending_adds >= search_op->target_pending_adds)
- send_pending_adds (search_op);
-
- if (cur_millis - search_op->grouping_time_start > GROUPING_MAXIMUM_WAIT) {
- GTimeVal new_start;
-
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
- search_op->target_pending_adds = MIN (GROUPING_MAXIMUM_SIZE,
- (search_op->num_sent_this_time + search_op->num_sent_last_time) / 2);
- search_op->target_pending_adds = MAX (search_op->target_pending_adds, 1);
-
-#ifdef PERFORMANCE_SPEW
- printf ("num sent this time %d, last time %d, target pending adds set to %d\n",
- search_op->num_sent_this_time,
- search_op->num_sent_last_time,
- search_op->target_pending_adds);
-#endif
- g_get_current_time (&new_start);
- search_op->grouping_time_start = TV_TO_MILLIS (new_start);
- search_op->num_sent_last_time = search_op->num_sent_this_time;
- search_op->num_sent_this_time = 0;
- }
- }
-}
-
-static void
ldap_search_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPSearchOp *search_op = (LDAPSearchOp*)op;
- PASBackendLDAPBookView *view = search_op->view;
+ PASBookView *view = search_op->view;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
LDAP *ldap = bl->priv->ldap;
LDAPMessage *e;
int msg_type;
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
+ bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL);
if (!search_op->notified_receiving_results) {
search_op->notified_receiving_results = TRUE;
@@ -2966,13 +2694,11 @@ ldap_search_handler (LDAPOp *op, LDAPMessage *res)
e = ldap_first_entry(ldap, res);
while (NULL != e) {
- ECardSimple *card = build_card_from_entry (ldap, e, NULL);
+ EContact *contact = build_contact_from_entry (ldap, e, NULL);
- search_op->pending_adds = g_list_append (search_op->pending_adds,
- e_card_simple_get_vcard_assume_utf8 (card));
- search_op->num_pending_adds ++;
+ pas_book_view_notify_update (view, contact);
- g_object_unref (card);
+ g_object_unref (contact);
e = ldap_next_entry(ldap, e);
}
@@ -2985,31 +2711,25 @@ ldap_search_handler (LDAPOp *op, LDAPMessage *res)
g_warning ("search returned %d\n", ldap_error);
- /* the entry that marks the end of our search */
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
-
if (ldap_error == LDAP_TIMELIMIT_EXCEEDED)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchTimeLimitExceeded);
else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchSizeLimitExceeded);
else if (ldap_error == LDAP_SUCCESS)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_Success);
else
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
ldap_op_finished (op);
}
else {
g_warning ("unhandled search result type %d returned", msg_type);
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
ldap_op_finished (op);
}
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
+ bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL);
}
static void
@@ -3017,14 +2737,11 @@ ldap_search_dtor (LDAPOp *op)
{
LDAPSearchOp *search_op = (LDAPSearchOp*) op;
+#if notyet
/* unhook us from our PASBackendLDAPBookView */
if (search_op->view)
search_op->view->search_op = NULL;
-
- g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL);
- g_list_free (search_op->pending_adds);
- search_op->pending_adds = NULL;
- search_op->num_pending_adds = 0;
+#endif
g_free (search_op);
}
@@ -3032,22 +2749,21 @@ ldap_search_dtor (LDAPOp *op)
static void
pas_backend_ldap_search (PASBackendLDAP *bl,
PASBook *book,
- PASBackendLDAPBookView *view)
+ PASBookView *view)
{
char *ldap_query;
- ldap_query = pas_backend_ldap_build_query(bl, view->search);
+ ldap_query = pas_backend_ldap_build_query (bl, pas_book_view_get_card_query (view));
if (ldap_query != NULL) {
LDAP *ldap = bl->priv->ldap;
int ldap_err;
- GTimeVal search_start;
int search_msgid;
printf ("searching server using filter: %s\n", ldap_query);
do {
- book_view_notify_status (view->book_view, _("Searching..."));
+ book_view_notify_status (view, _("Searching..."));
ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn,
bl->priv->ldap_scope,
@@ -3056,33 +2772,30 @@ pas_backend_ldap_search (PASBackendLDAP *bl,
NULL, /* XXX */
NULL, /* XXX */
NULL, /* XXX timeout */
- view->limit, &search_msgid);
- } while (pas_backend_ldap_reconnect (bl, view->book_view, ldap_err));
+ 0 /* XXX we need this back in view->limit*/, &search_msgid);
+ } while (pas_backend_ldap_reconnect (bl, view, ldap_err));
g_free (ldap_query);
if (ldap_err != LDAP_SUCCESS) {
- book_view_notify_status (view->book_view, ldap_err2string(ldap_err));
+ book_view_notify_status (view, ldap_err2string(ldap_err));
return;
}
else if (search_msgid == -1) {
- book_view_notify_status (view->book_view,
+ book_view_notify_status (view,
_("Error performing search"));
return;
}
else {
LDAPSearchOp *op = g_new0 (LDAPSearchOp, 1);
- op->target_pending_adds = GROUPING_INITIAL_SIZE;
-
- g_get_current_time (&search_start);
- op->grouping_time_start = TV_TO_MILLIS (search_start);
-
op->view = view;
+#if notyet
view->search_op = (LDAPOp*)op;
+#endif
- ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view->book_view,
+ ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view,
search_msgid,
ldap_search_handler, ldap_search_dtor);
@@ -3090,106 +2803,49 @@ pas_backend_ldap_search (PASBackendLDAP *bl,
return;
}
else {
- pas_book_view_notify_complete (view->book_view,
- GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery);
+ pas_book_view_notify_complete (view,
+ GNOME_Evolution_Addressbook_InvalidQuery);
return;
}
}
static void
-ldap_get_view (PASBackend *backend,
- PASBook *book,
- const char *search,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- int limit)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- PASBookView *book_view;
- PASBackendLDAPBookView *view;
-
- book_view = pas_book_view_new (listener);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- view = g_new0(PASBackendLDAPBookView, 1);
- view->book_view = book_view;
- view->search = g_strdup(search);
- view->card_sexp = pas_backend_card_sexp_new (view->search);
- view->blpriv = bl->priv;
- view->limit = limit;
-
- e_list_append(bl->priv->book_views, view);
-
- pas_book_respond_get_book_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- pas_backend_ldap_search (bl, book, view);
-
- bonobo_object_unref (BONOBO_OBJECT (book_view));
-}
-
-static void
-pas_backend_ldap_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- ldap_get_view (backend, book, req->search, req->listener,
- bl->priv->ldap_limit);
-}
-
-static void
-pas_backend_ldap_process_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
+pas_backend_ldap_process_start_book_view (PASBackend *backend,
+ PASBookView *view)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- ldap_get_view (backend, book, req->search, req->listener,
- MIN (bl->priv->ldap_limit, 100));
+ pas_backend_ldap_search (bl, NULL /* XXX ugh */, view);
}
static void
pas_backend_ldap_process_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req)
+ const char *change_id)
{
/* FIXME: implement */
}
-static void
-pas_backend_ldap_process_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- pas_book_report_connection (book, bl->priv->connected);
-}
-
#define LDAP_SIMPLE_PREFIX "ldap/simple-"
#define SASL_PREFIX "sasl/"
static void
pas_backend_ldap_process_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req)
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
int ldap_error;
char *dn = NULL;
- if (!strncasecmp (req->auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) {
+ if (!strncasecmp (auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) {
- if (!strcmp (req->auth_method, "ldap/simple-email")) {
+ if (!strcmp (auth_method, "ldap/simple-email")) {
LDAPMessage *res, *e;
- char *query = g_strdup_printf ("(mail=%s)", req->user);
+ char *query = g_strdup_printf ("(mail=%s)", user);
ldap_error = ldap_search_s (bl->priv->ldap,
bl->priv->ldap_rootdn,
@@ -3211,37 +2867,37 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
}
else {
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_PermissionDenied);
+ GNOME_Evolution_Addressbook_PermissionDenied);
return;
}
}
- else if (!strcmp (req->auth_method, "ldap/simple-binddn")) {
- dn = g_strdup (req->user);
+ else if (!strcmp (auth_method, "ldap/simple-binddn")) {
+ dn = g_strdup (user);
}
/* now authenticate against the DN we were either supplied or queried for */
printf ("simple auth as %s\n", dn);
ldap_error = ldap_simple_bind_s(bl->priv->ldap,
dn,
- req->passwd);
+ passwd);
pas_book_respond_authenticate_user (book,
ldap_error_to_response (ldap_error));
}
#ifdef ENABLE_SASL_BINDS
- else if (!strncasecmp (req->auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
- g_print ("sasl bind (mech = %s) as %s", req->auth_method + strlen (SASL_PREFIX), req->user);
+ else if (!strncasecmp (auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
+ g_print ("sasl bind (mech = %s) as %s", auth_method + strlen (SASL_PREFIX), user);
ldap_error = ldap_sasl_bind_s (bl->priv->ldap,
NULL,
- req->auth_method + strlen (SASL_PREFIX),
- req->passwd,
+ auth_method + strlen (SASL_PREFIX),
+ passwd,
NULL,
NULL,
NULL);
if (ldap_error == LDAP_NOT_SUPPORTED)
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod);
+ GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod);
else
pas_book_respond_authenticate_user (book,
ldap_error_to_response (ldap_error));
@@ -3249,13 +2905,13 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
#endif
else {
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod);
+ GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod);
return;
}
if (ldap_error == LDAP_SUCCESS) {
bl->priv->auth_dn = dn;
- bl->priv->auth_passwd = g_strdup (req->passwd);
+ bl->priv->auth_passwd = g_strdup (passwd);
pas_backend_set_is_writable (backend, TRUE);
@@ -3281,33 +2937,32 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
static void
pas_backend_ldap_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+ PASBook *book)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
+ GNOME_Evolution_Addressbook_Success,
bl->priv->supported_fields);
}
static void
pas_backend_ldap_process_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req)
+ PASBook *book)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
pas_book_respond_get_supported_auth_methods (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
+ GNOME_Evolution_Addressbook_Success,
bl->priv->supported_auth_methods);
}
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_ldap_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
LDAPURLDesc *lud;
@@ -3383,17 +3038,7 @@ pas_backend_ldap_load_uri (PASBackend *backend,
return pas_backend_ldap_connect (bl);
} else
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-}
-
-/* Get_uri handler for the addressbook LDAP backend */
-static const char *
-pas_backend_ldap_get_uri (PASBackend *backend)
-{
- PASBackendLDAP *bl;
-
- bl = PAS_BACKEND_LDAP (backend);
- return bl->priv->uri;
+ return GNOME_Evolution_Addressbook_OtherError;
}
static char*
@@ -3459,13 +3104,15 @@ pas_backend_ldap_dispose (GObject *object)
g_source_remove (bl->priv->poll_timeout);
}
- g_object_unref (bl->priv->book_views);
-
- if (bl->priv->supported_fields)
- g_object_unref (bl->priv->supported_fields);
+ if (bl->priv->supported_fields) {
+ g_list_foreach (bl->priv->supported_fields, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_fields);
+ }
- if (bl->priv->supported_auth_methods)
- g_object_unref (bl->priv->supported_auth_methods);
+ if (bl->priv->supported_auth_methods) {
+ g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_auth_methods);
+ }
g_free (bl->priv->uri);
@@ -3492,17 +3139,13 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
/* Set the virtual methods. */
parent_class->load_uri = pas_backend_ldap_load_uri;
- parent_class->get_uri = pas_backend_ldap_get_uri;
parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities;
- parent_class->create_card = pas_backend_ldap_process_create_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;
- parent_class->get_cursor = pas_backend_ldap_process_get_cursor;
- parent_class->get_book_view = pas_backend_ldap_process_get_book_view;
- parent_class->get_completion_view = pas_backend_ldap_process_get_completion_view;
+ parent_class->create_contact = pas_backend_ldap_process_create_contact;
+ parent_class->remove_contacts = pas_backend_ldap_process_remove_contacts;
+ parent_class->modify_contact = pas_backend_ldap_process_modify_contact;
+ parent_class->get_contact = pas_backend_ldap_process_get_contact;
+ parent_class->start_book_view = pas_backend_ldap_process_start_book_view;
parent_class->get_changes = pas_backend_ldap_process_get_changes;
parent_class->authenticate_user = pas_backend_ldap_process_authenticate_user;
parent_class->get_supported_fields = pas_backend_ldap_process_get_supported_fields;
@@ -3518,11 +3161,11 @@ pas_backend_ldap_init (PASBackendLDAP *backend)
priv = g_new0 (PASBackendLDAPPrivate, 1);
- priv->supported_fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
- priv->ldap_limit = 100;
- priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal);
- priv->poll_timeout = -1;
- priv->book_views = e_list_new (NULL, NULL, NULL);
+ priv->supported_fields = NULL;
+ priv->supported_auth_methods = NULL;
+ priv->ldap_limit = 100;
+ priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal);
+ priv->poll_timeout = -1;
backend->priv = priv;
}
diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c
index 6c2c9a45c8..15f12cebc1 100644
--- a/addressbook/backend/pas/pas-backend-summary.c
+++ b/addressbook/backend/pas/pas-backend-summary.c
@@ -33,7 +33,7 @@
#include <gal/widgets/e-unicode.h>
-#include "ebook/e-card-simple.h"
+#include "ebook/e-contact.h"
#include "pas-backend-summary.h"
#include "e-util/e-sexp.h"
@@ -689,36 +689,29 @@ pas_backend_summary_save (PASBackendSummary *summary)
}
void
-pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard)
+pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact)
{
- ECard *card;
- ECardSimple *simple;
PASBackendSummaryItem *new_item;
- card = e_card_new ((char*)vcard);
- simple = e_card_simple_new (card);
-
- new_item = g_new (PASBackendSummaryItem, 1);
-
- new_item->id = g_strdup (e_card_simple_get_id (simple));
- new_item->nickname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_NICKNAME);
- new_item->full_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FULL_NAME);
- new_item->given_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME);
- new_item->surname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME);
- new_item->file_as = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- new_item->email_1 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL);
- new_item->email_2 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_2);
- new_item->email_3 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_3);
- new_item->list = e_card_evolution_list (card);
- new_item->list_show_addresses = e_card_evolution_list_show_addresses (card);
- new_item->wants_html = card->wants_html;
- new_item->wants_html_set = card->wants_html_set;
+ new_item = g_new0 (PASBackendSummaryItem, 1);
+
+ new_item->id = e_contact_get (contact, E_CONTACT_UID);
+ new_item->nickname = e_contact_get (contact, E_CONTACT_NICKNAME);
+ new_item->full_name = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ new_item->given_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
+ new_item->surname = e_contact_get (contact, E_CONTACT_FAMILY_NAME);
+ new_item->file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+ new_item->email_1 = e_contact_get (contact, E_CONTACT_EMAIL_1);
+ new_item->email_2 = e_contact_get (contact, E_CONTACT_EMAIL_2);
+ new_item->email_3 = e_contact_get (contact, E_CONTACT_EMAIL_3);
+ new_item->list = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_IS_LIST));
+ new_item->list_show_addresses = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_LIST_SHOW_ADDRESSES));
+ new_item->wants_html = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_WANTS_HTML));
g_ptr_array_add (summary->priv->items, new_item);
g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item);
- g_object_unref (simple);
- g_object_unref (card);
+ g_object_unref (contact);
#ifdef SUMMARY_STATS
summary->priv->size += sizeof (PASBackendSummaryItem);
@@ -736,7 +729,7 @@ pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard)
}
void
-pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id)
+pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id)
{
PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id);
@@ -748,7 +741,7 @@ pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id)
return;
}
- g_warning ("pas_backend_summary_remove_card: unable to locate id `%s'", id);
+ g_warning ("pas_backend_summary_remove_contact: unable to locate id `%s'", id);
}
static gboolean
@@ -1056,31 +1049,26 @@ pas_backend_summary_get_summary_vcard(PASBackendSummary *summary, const char *id
PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id);
if (item) {
- ECard *card = e_card_new ("");
- ECardSimple *simple = e_card_simple_new (card);
+ EContact *contact = e_contact_new ();
char *vcard;
- e_card_simple_set_id (simple, item->id);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FILE_AS, item->file_as);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME, item->given_name);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME, item->surname);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_NICKNAME, item->nickname);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, item->full_name);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL, item->email_1);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, item->email_2);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, item->email_3);
+ e_contact_set (contact, E_CONTACT_UID, item->id);
+ e_contact_set (contact, E_CONTACT_FILE_AS, item->file_as);
+ e_contact_set (contact, E_CONTACT_GIVEN_NAME, item->given_name);
+ e_contact_set (contact, E_CONTACT_FAMILY_NAME, item->surname);
+ e_contact_set (contact, E_CONTACT_NICKNAME, item->nickname);
+ e_contact_set (contact, E_CONTACT_FULL_NAME, item->full_name);
+ e_contact_set (contact, E_CONTACT_EMAIL_1, item->email_1);
+ e_contact_set (contact, E_CONTACT_EMAIL_2, item->email_2);
+ e_contact_set (contact, E_CONTACT_EMAIL_3, item->email_3);
- e_card_simple_sync_card (simple);
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (item->list));
+ e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (item->list_show_addresses));
+ e_contact_set (contact, E_CONTACT_WANTS_HTML, GINT_TO_POINTER (item->wants_html));
- card->list = item->list;
- card->wants_html = item->wants_html;
- card->wants_html_set = item->wants_html_set;
- card->list_show_addresses = item->list_show_addresses;
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- vcard = e_card_simple_get_vcard (simple);
-
- g_object_unref (simple);
- g_object_unref (card);
+ g_object_unref (contact);
return vcard;
}
diff --git a/addressbook/backend/pas/pas-backend-summary.h b/addressbook/backend/pas/pas-backend-summary.h
index 54083855d5..bb07e0fb27 100644
--- a/addressbook/backend/pas/pas-backend-summary.h
+++ b/addressbook/backend/pas/pas-backend-summary.h
@@ -26,6 +26,8 @@
#include <glib.h>
#include <glib-object.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BACKEND_SUMMARY (pas_backend_summary_get_type ())
#define PAS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummary))
@@ -36,14 +38,14 @@
typedef struct _PASBackendSummaryPrivate PASBackendSummaryPrivate;
-typedef struct {
+struct _PASBackendSummary{
GObject parent_object;
PASBackendSummaryPrivate *priv;
-} PASBackendSummary;
+};
-typedef struct {
+struct _PASBackendSummaryClass{
GObjectClass parent_class;
-} PASBackendSummaryClass;
+};
PASBackendSummary* pas_backend_summary_new (const char *summary_path,
int flush_timeout_millis);
@@ -55,8 +57,8 @@ gboolean pas_backend_summary_load (PASBackendSummary *summ
/* returns FALSE if the save fails, TRUE if it succeeds (or isn't required due to no changes) */
gboolean pas_backend_summary_save (PASBackendSummary *summary);
-void pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard);
-void pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id);
+void pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact);
+void pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id);
void pas_backend_summary_touch (PASBackendSummary *summary);
diff --git a/addressbook/backend/pas/pas-backend-sync.c b/addressbook/backend/pas/pas-backend-sync.c
new file mode 100644
index 0000000000..45063eddc6
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-sync.c
@@ -0,0 +1,395 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ *
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#include <config.h>
+#include "pas-backend-sync.h"
+#include "pas-marshal.h"
+
+struct _PASBackendSyncPrivate {
+ int mumble;
+};
+
+static GObjectClass *parent_class;
+
+gboolean
+pas_backend_sync_construct (PASBackendSync *backend)
+{
+ return TRUE;
+}
+
+PASBackendSyncStatus
+pas_backend_sync_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync) (backend, book, vcard, contact);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_remove (PASBackendSync *backend,
+ PASBook *book)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync) (backend, book);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **removed_ids)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (id_list, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (removed_ids, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync) (backend, book, id_list, removed_ids);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync) (backend, book, vcard, contact);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (id, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync) (backend, book, id, vcard);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (query, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contacts, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync) (backend, book, query, contacts);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_changes (PASBackendSync *backend,
+ PASBook *book,
+ const char *change_id,
+ GList **changes)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (change_id, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (changes, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync) (backend, book, change_id, changes);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (user && passwd && auth_method, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, book, user, passwd, auth_method);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (fields, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync) (backend, book, fields);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend,
+ PASBook *book,
+ GList **methods)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (methods, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync) (backend, book, methods);
+}
+
+static void
+_pas_backend_remove (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+
+ status = pas_backend_sync_remove (PAS_BACKEND_SYNC (backend), book);
+
+ pas_book_respond_remove (book, status);
+}
+
+static void
+_pas_backend_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
+{
+ PASBackendSyncStatus status;
+ EContact *contact;
+
+ status = pas_backend_sync_create_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact);
+
+ pas_book_respond_create (book, status, contact);
+
+ g_object_unref (contact);
+}
+
+static void
+_pas_backend_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *id_list)
+{
+ PASBackendSyncStatus status;
+ GList *ids = NULL;
+
+ status = pas_backend_sync_remove_contacts (PAS_BACKEND_SYNC (backend), book, id_list, &ids);
+
+ pas_book_respond_remove_contacts (book, status, ids);
+
+ g_list_free (ids);
+}
+
+static void
+_pas_backend_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
+{
+ PASBackendSyncStatus status;
+ EContact *contact;
+
+ status = pas_backend_sync_modify_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact);
+
+ pas_book_respond_modify (book, status, contact);
+
+ g_object_unref (contact);
+}
+
+static void
+_pas_backend_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
+{
+ PASBackendSyncStatus status;
+ char *vcard;
+
+ status = pas_backend_sync_get_contact (PAS_BACKEND_SYNC (backend), book, id, &vcard);
+
+ pas_book_respond_get_contact (book, status, vcard);
+
+ g_free (vcard);
+}
+
+static void
+_pas_backend_get_contact_list (PASBackend *backend,
+ PASBook *book,
+ const char *query)
+{
+ PASBackendSyncStatus status;
+ GList *cards = NULL;
+
+ status = pas_backend_sync_get_contact_list (PAS_BACKEND_SYNC (backend), book, query, &cards);
+
+ pas_book_respond_get_contact_list (book, status, cards);
+}
+
+static void
+_pas_backend_get_changes (PASBackend *backend,
+ PASBook *book,
+ const char *change_id)
+{
+ PASBackendSyncStatus status;
+ GList *changes = NULL;
+
+ status = pas_backend_sync_get_changes (PAS_BACKEND_SYNC (backend), book, change_id, &changes);
+
+ pas_book_respond_get_changes (book, status, changes);
+
+ /* XXX free view? */
+}
+
+static void
+_pas_backend_authenticate_user (PASBackend *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ PASBackendSyncStatus status;
+
+ status = pas_backend_sync_authenticate_user (PAS_BACKEND_SYNC (backend), book, user, passwd, auth_method);
+
+ pas_book_respond_authenticate_user (book, status);
+}
+
+static void
+_pas_backend_get_supported_fields (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+ GList *fields = NULL;
+
+ status = pas_backend_sync_get_supported_fields (PAS_BACKEND_SYNC (backend), book, &fields);
+
+ pas_book_respond_get_supported_fields (book, status, fields);
+
+ g_list_foreach (fields, (GFunc)g_free, NULL);
+ g_list_free (fields);
+}
+
+static void
+_pas_backend_get_supported_auth_methods (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+ GList *methods = NULL;
+
+ status = pas_backend_sync_get_supported_auth_methods (PAS_BACKEND_SYNC (backend), book, &methods);
+
+ pas_book_respond_get_supported_auth_methods (book, status, methods);
+
+ g_list_foreach (methods, (GFunc)g_free, NULL);
+ g_list_free (methods);
+}
+
+static void
+pas_backend_sync_init (PASBackendSync *backend)
+{
+ PASBackendSyncPrivate *priv;
+
+ priv = g_new0 (PASBackendSyncPrivate, 1);
+
+ backend->priv = priv;
+}
+
+static void
+pas_backend_sync_dispose (GObject *object)
+{
+ PASBackendSync *backend;
+
+ backend = PAS_BACKEND_SYNC (object);
+
+ if (backend->priv) {
+ g_free (backend->priv);
+
+ backend->priv = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+pas_backend_sync_class_init (PASBackendSyncClass *klass)
+{
+ GObjectClass *object_class;
+ PASBackendClass *backend_class = PAS_BACKEND_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class = (GObjectClass *) klass;
+
+ backend_class->remove = _pas_backend_remove;
+ backend_class->create_contact = _pas_backend_create_contact;
+ backend_class->remove_contacts = _pas_backend_remove_contacts;
+ backend_class->modify_contact = _pas_backend_modify_contact;
+ backend_class->get_contact = _pas_backend_get_contact;
+ backend_class->get_contact_list = _pas_backend_get_contact_list;
+ backend_class->get_changes = _pas_backend_get_changes;
+ backend_class->authenticate_user = _pas_backend_authenticate_user;
+ backend_class->get_supported_fields = _pas_backend_get_supported_fields;
+ backend_class->get_supported_auth_methods = _pas_backend_get_supported_auth_methods;
+
+ object_class->dispose = pas_backend_sync_dispose;
+}
+
+/**
+ * pas_backend_get_type:
+ */
+GType
+pas_backend_sync_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo info = {
+ sizeof (PASBackendSyncClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) pas_backend_sync_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PASBackendSync),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pas_backend_sync_init
+ };
+
+ type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendSync", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/backend/pas/pas-backend-sync.h b/addressbook/backend/pas/pas-backend-sync.h
new file mode 100644
index 0000000000..2e176d9f5d
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-sync.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ */
+
+#ifndef __PAS_BACKEND_SYNC_H__
+#define __PAS_BACKEND_SYNC_H__
+
+#include <glib.h>
+#include <pas/pas-types.h>
+#include <pas/pas-backend.h>
+#include <pas/addressbook.h>
+
+#define PAS_TYPE_BACKEND_SYNC (pas_backend_sync_get_type ())
+#define PAS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SYNC, PASBackendSync))
+#define PAS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass))
+#define PAS_IS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_SYNC))
+#define PAS_IS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_SYNC))
+#define PAS_BACKEND_SYNC_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass))
+
+typedef struct _PASBackendSyncPrivate PASBackendSyncPrivate;
+
+typedef GNOME_Evolution_Addressbook_CallStatus PASBackendSyncStatus;
+
+struct _PASBackendSync {
+ PASBackend parent_object;
+ PASBackendSyncPrivate *priv;
+};
+
+struct _PASBackendSyncClass {
+ PASBackendClass parent_class;
+
+ /* Virtual methods */
+ PASBackendSyncStatus (*remove_sync) (PASBackendSync *backend, PASBook *book);
+ PASBackendSyncStatus (*create_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *vcard, EContact **contact);
+ PASBackendSyncStatus (*remove_contacts_sync) (PASBackendSync *backend, PASBook *book,
+ GList *id_list, GList **removed_ids);
+ PASBackendSyncStatus (*modify_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *vcard, EContact **contact);
+ PASBackendSyncStatus (*get_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *id, char **vcard);
+ PASBackendSyncStatus (*get_contact_list_sync) (PASBackendSync *backend, PASBook *book,
+ const char *query, GList **contacts);
+ PASBackendSyncStatus (*get_changes_sync) (PASBackendSync *backend, PASBook *book,
+ const char *change_id, GList **changes);
+ PASBackendSyncStatus (*authenticate_user_sync) (PASBackendSync *backend, PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method);
+ PASBackendSyncStatus (*get_supported_fields_sync) (PASBackendSync *backend, PASBook *book,
+ GList **fields);
+ PASBackendSyncStatus (*get_supported_auth_methods_sync) (PASBackendSync *backend, PASBook *book,
+ GList **methods);
+
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+
+};
+
+typedef PASBackendSync * (*PASBackendSyncFactoryFn) (void);
+
+gboolean pas_backend_sync_construct (PASBackendSync *backend);
+
+GType pas_backend_sync_get_type (void);
+
+PASBackendSyncStatus pas_backend_sync_remove (PASBackendSync *backend, PASBook *book);
+PASBackendSyncStatus pas_backend_sync_create_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact);
+PASBackendSyncStatus pas_backend_sync_remove_contacts (PASBackendSync *backend, PASBook *book, GList *id_list, GList **removed_ids);
+PASBackendSyncStatus pas_backend_sync_modify_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact);
+PASBackendSyncStatus pas_backend_sync_get_contact (PASBackendSync *backend, PASBook *book, const char *id, char **vcard);
+PASBackendSyncStatus pas_backend_sync_get_contact_list (PASBackendSync *backend, PASBook *book, const char *query, GList **contacts);
+PASBackendSyncStatus pas_backend_sync_get_changes (PASBackendSync *backend, PASBook *book, const char *change_id, GList **changes);
+PASBackendSyncStatus pas_backend_sync_authenticate_user (PASBackendSync *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method);
+PASBackendSyncStatus pas_backend_sync_get_supported_fields (PASBackendSync *backend, PASBook *book, GList **fields);
+PASBackendSyncStatus pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend, PASBook *book, GList **methods);
+
+#endif /* ! __PAS_BACKEND_SYNC_H__ */
diff --git a/addressbook/backend/pas/pas-backend-vcf.c b/addressbook/backend/pas/pas-backend-vcf.c
new file mode 100644
index 0000000000..3765fd978e
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-vcf.c
@@ -0,0 +1,632 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ *
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#include "config.h"
+#include "pas-backend-vcf.h"
+#include "pas-backend-card-sexp.h"
+#include "pas-book.h"
+#include "pas-book-view.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#include <gal/util/e-util.h>
+#include <gal/widgets/e-unicode.h>
+
+#include <ebook/e-contact.h>
+#include <libgnome/gnome-i18n.h>
+
+#define PAS_ID_PREFIX "pas-id-"
+#define FILE_FLUSH_TIMEOUT 5000
+
+static PASBackendSyncClass *pas_backend_vcf_parent_class;
+typedef struct _PASBackendVCFBookView PASBackendVCFBookView;
+typedef struct _PASBackendVCFSearchContext PASBackendVCFSearchContext;
+
+struct _PASBackendVCFPrivate {
+ char *uri;
+ char *filename;
+ GHashTable *contacts;
+ gboolean dirty;
+ int flush_timeout_tag;
+};
+
+static char *
+pas_backend_vcf_create_unique_id ()
+{
+ /* use a 32 counter and the 32 bit timestamp to make an id.
+ it's doubtful 2^32 id's will be created in a second, so we
+ should be okay. */
+ static guint c = 0;
+ return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++);
+}
+
+typedef struct {
+ PASBackendVCF *bvcf;
+ PASBook *book;
+ PASBookView *view;
+} VCFBackendSearchClosure;
+
+static void
+free_search_closure (VCFBackendSearchClosure *closure)
+{
+ g_free (closure);
+}
+
+static void
+foreach_search_compare (char *id, char *vcard_string, VCFBackendSearchClosure *closure)
+{
+ EContact *contact;
+
+ contact = e_contact_new_from_vcard (vcard_string);
+ pas_book_view_notify_update (closure->view, contact);
+ g_object_unref (contact);
+}
+
+static gboolean
+pas_backend_vcf_search_timeout (gpointer data)
+{
+ VCFBackendSearchClosure *closure = data;
+
+ g_hash_table_foreach (closure->bvcf->priv->contacts,
+ (GHFunc)foreach_search_compare,
+ closure);
+
+ pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success);
+
+ free_search_closure (closure);
+
+ return FALSE;
+}
+
+
+static void
+pas_backend_vcf_search (PASBackendVCF *bvcf,
+ PASBookView *book_view)
+{
+ const char *query = pas_book_view_get_card_query (book_view);
+ VCFBackendSearchClosure *closure = g_new0 (VCFBackendSearchClosure, 1);
+
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ pas_book_view_notify_status_message (book_view, _("Loading..."));
+ else
+ pas_book_view_notify_status_message (book_view, _("Searching..."));
+
+ closure->view = book_view;
+ closure->bvcf = bvcf;
+
+ g_idle_add (pas_backend_vcf_search_timeout, closure);
+}
+
+static void
+insert_contact (PASBackendVCF *vcf, char *vcard)
+{
+ EContact *contact = e_contact_new_from_vcard (vcard);
+ char *id;
+
+ id = e_contact_get (contact, E_CONTACT_UID);
+ if (id)
+ g_hash_table_insert (vcf->priv->contacts,
+ id,
+ e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
+}
+
+static void
+load_file (PASBackendVCF *vcf)
+{
+ FILE *fp;
+ GString *str;
+ char buf[1024];
+
+ fp = fopen (vcf->priv->filename, "r");
+ if (!fp) {
+ g_warning ("failed to open `%s' for reading", vcf->priv->filename);
+ return;
+ }
+
+ str = g_string_new ("");
+
+ while (fgets (buf, sizeof (buf), fp)) {
+ if (!strcmp (buf, "\r\n")) {
+ /* if the string has accumulated some stuff, create a contact for it and start over */
+ if (str->len) {
+ insert_contact (vcf, str->str);
+ g_string_assign (str, "");
+ }
+ }
+ else {
+ g_string_append (str, buf);
+ }
+ }
+ if (str->len) {
+ insert_contact (vcf, str->str);
+ }
+
+ g_string_free (str, TRUE);
+
+ fclose (fp);
+}
+
+static void
+foreach_build_list (char *id, char *vcard_string, GList **list)
+{
+ *list = g_list_append (*list, e_contact_new_from_vcard (vcard_string));
+}
+
+static gboolean
+save_file (PASBackendVCF *vcf)
+{
+ GList *contacts = NULL;
+ GList *l;
+ char *new_path;
+ int fd, rv;
+
+ g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &contacts);
+
+ new_path = g_strdup_printf ("%s.new", vcf->priv->filename);
+
+ fd = open (new_path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+
+ for (l = contacts; l; l = l->next) {
+ EContact *contact = l->data;
+ char *vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ int len = strlen (vcard_str);
+
+ rv = write (fd, vcard_str, len);
+ g_free (vcard_str);
+ if (rv < len) {
+ /* XXX */
+ g_warning ("write failed. we need to handle short writes\n");
+ close (fd);
+ unlink (new_path);
+ return FALSE;
+ }
+
+ rv = write (fd, "\r\n", 2);
+ if (rv < 2) {
+ /* XXX */
+ g_warning ("write failed. we need to handle short writes\n");
+ close (fd);
+ unlink (new_path);
+ return FALSE;
+ }
+ }
+
+ if (0 > rename (new_path, vcf->priv->filename)) {
+ g_warning ("Failed to rename %s: %s\n", vcf->priv->filename, strerror(errno));
+ unlink (new_path);
+ return FALSE;
+ }
+
+ g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (contacts);
+ g_free (new_path);
+
+ vcf->priv->dirty = FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+vcf_flush_file (gpointer data)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (data);
+
+ if (!bvcf->priv->dirty) {
+ bvcf->priv->flush_timeout_tag = 0;
+ return FALSE;
+ }
+
+ if (!save_file (bvcf)) {
+ g_warning ("failed to flush the .vcf file to disk, will try again next timeout");
+ return TRUE;
+ }
+
+ bvcf->priv->flush_timeout_tag = 0;
+ return FALSE;
+}
+
+static EContact *
+do_create(PASBackendVCF *bvcf,
+ const char *vcard_req,
+ gboolean dirty_the_file)
+{
+ char *id;
+ EContact *contact;
+ char *vcard;
+
+ id = pas_backend_vcf_create_unique_id ();
+
+ contact = e_contact_new_from_vcard (vcard_req);
+ e_contact_set(contact, E_CONTACT_UID, id);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+
+ g_hash_table_insert (bvcf->priv->contacts, id, vcard);
+
+ if (dirty_the_file) {
+ bvcf->priv->dirty = TRUE;
+
+ if (!bvcf->priv->flush_timeout_tag)
+ bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
+ vcf_flush_file, bvcf);
+ }
+
+ return contact;
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+
+ *contact = do_create(bvcf, vcard, TRUE);
+ if (*contact) {
+ return GNOME_Evolution_Addressbook_Success;
+ }
+ else {
+ /* XXX need a different call status for this case, i
+ think */
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **ids)
+{
+ /* FIXME: make this handle bulk deletes like the file backend does */
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *id = id_list->data;
+
+ if (!g_hash_table_remove (bvcf->priv->contacts, id)) {
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+ else {
+ bvcf->priv->dirty = TRUE;
+ if (!bvcf->priv->flush_timeout_tag)
+ bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
+ vcf_flush_file, bvcf);
+
+ *ids = g_list_append (*ids, id);
+
+ return GNOME_Evolution_Addressbook_Success;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *old_id, *old_vcard_string;
+ const char *id;
+
+ /* create a new ecard from the request data */
+ *contact = e_contact_new_from_vcard (vcard);
+ id = e_contact_get_const (*contact, E_CONTACT_UID);
+
+ if (!g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string)) {
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+ else {
+ g_hash_table_insert (bvcf->priv->contacts, old_id, g_strdup (vcard));
+
+ g_free (old_vcard_string);
+
+ return GNOME_Evolution_Addressbook_Success;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *v;
+
+ v = g_hash_table_lookup (bvcf->priv->contacts, id);
+
+ if (v) {
+ *vcard = g_strdup (v);
+ return GNOME_Evolution_Addressbook_Success;
+ } else {
+ *vcard = g_strdup ("");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+}
+
+
+typedef struct {
+ PASBackendVCF *bvcf;
+ gboolean search_needed;
+ PASBackendCardSExp *card_sexp;
+ GList *list;
+} GetContactListClosure;
+
+static void
+foreach_get_contact_compare (char *id, char *vcard_string, GetContactListClosure *closure)
+{
+ if ((!closure->search_needed) || pas_backend_card_sexp_match_vcard (closure->card_sexp, vcard_string)) {
+ closure->list = g_list_append (closure->list, g_strdup (vcard_string));
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ const char *search = query;
+ GetContactListClosure closure;
+
+ closure.bvcf = bvcf;
+ closure.search_needed = strcmp (search, "(contains \"x-evolution-any-field\" \"\")");
+ closure.card_sexp = pas_backend_card_sexp_new (search);
+ closure.list = NULL;
+
+ g_hash_table_foreach (bvcf->priv->contacts, (GHFunc)foreach_get_contact_compare, &closure);
+
+ g_object_unref (closure.card_sexp);
+
+ *contacts = closure.list;
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static void
+pas_backend_vcf_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
+{
+ pas_backend_vcf_search (PAS_BACKEND_VCF (backend), book_view);
+}
+
+static char *
+pas_backend_vcf_extract_path_from_uri (const char *uri)
+{
+ g_assert (strncasecmp (uri, "vcf://", 6) == 0);
+
+ return g_strdup (uri + 6);
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields_out)
+{
+ GList *fields = NULL;
+ int i;
+
+ /* XXX we need a way to say "we support everything", since the
+ vcf backend does */
+ for (i = 0; i < E_CONTACT_FIELD_LAST; i ++)
+ fields = g_list_append (fields, (char*)e_contact_field_name (i));
+
+ *fields_out = fields;
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+#include "ximian-vcard.h"
+
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_vcf_load_uri (PASBackend *backend,
+ const char *uri,
+ gboolean only_if_exists)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *filename;
+ gboolean writable = FALSE;
+ int fd;
+
+ g_free(bvcf->priv->uri);
+ bvcf->priv->uri = g_strdup (uri);
+
+ bvcf->priv->filename = filename = pas_backend_vcf_extract_path_from_uri (uri);
+
+ fd = open (filename, O_RDWR);
+
+ bvcf->priv->contacts = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ if (fd != -1) {
+ writable = TRUE;
+ } else {
+ fd = open (filename, O_RDONLY);
+
+ if (fd == -1) {
+ fd = open (filename, O_CREAT, 0666);
+
+ if (fd != -1 && !only_if_exists) {
+ EContact *contact;
+
+ contact = do_create(bvcf, XIMIAN_VCARD, FALSE);
+ save_file (bvcf);
+
+ /* XXX check errors here */
+ g_object_unref (contact);
+
+ writable = TRUE;
+ }
+ }
+ }
+
+ if (fd == -1) {
+ g_warning ("Failed to open addressbook at uri `%s'", uri);
+ g_warning ("error == %s", strerror(errno));
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+
+ close (fd); /* XXX ugh */
+ load_file (bvcf);
+
+ pas_backend_set_is_loaded (backend, TRUE);
+ pas_backend_set_is_writable (backend, writable);
+
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static char *
+pas_backend_vcf_get_static_capabilities (PASBackend *backend)
+{
+ return g_strdup("local,do-initial-query");
+}
+
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_vcf_cancel_operation (PASBackend *backend, PASBook *book)
+{
+ return GNOME_Evolution_Addressbook_CouldNotCancel;
+}
+
+static gboolean
+pas_backend_vcf_construct (PASBackendVCF *backend)
+{
+ g_assert (backend != NULL);
+ g_assert (PAS_IS_BACKEND_VCF (backend));
+
+ if (! pas_backend_construct (PAS_BACKEND (backend)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * pas_backend_vcf_new:
+ */
+PASBackend *
+pas_backend_vcf_new (void)
+{
+ PASBackendVCF *backend;
+
+ backend = g_object_new (PAS_TYPE_BACKEND_VCF, NULL);
+
+ if (! pas_backend_vcf_construct (backend)) {
+ g_object_unref (backend);
+
+ return NULL;
+ }
+
+ return PAS_BACKEND (backend);
+}
+
+static void
+pas_backend_vcf_dispose (GObject *object)
+{
+ PASBackendVCF *bvcf;
+
+ bvcf = PAS_BACKEND_VCF (object);
+
+ if (bvcf->priv) {
+
+ if (bvcf->priv->dirty)
+ save_file (bvcf);
+
+ if (bvcf->priv->flush_timeout_tag) {
+ g_source_remove (bvcf->priv->flush_timeout_tag);
+ bvcf->priv->flush_timeout_tag = 0;
+ }
+
+ g_free (bvcf->priv->uri);
+ g_free (bvcf->priv->filename);
+
+ g_free (bvcf->priv);
+ bvcf->priv = NULL;
+ }
+
+ G_OBJECT_CLASS (pas_backend_vcf_parent_class)->dispose (object);
+}
+
+static void
+pas_backend_vcf_class_init (PASBackendVCFClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PASBackendSyncClass *sync_class;
+ PASBackendClass *backend_class;
+
+ pas_backend_vcf_parent_class = g_type_class_peek_parent (klass);
+
+ sync_class = PAS_BACKEND_SYNC_CLASS (klass);
+ backend_class = PAS_BACKEND_CLASS (klass);
+
+ /* Set the virtual methods. */
+ backend_class->load_uri = pas_backend_vcf_load_uri;
+ backend_class->get_static_capabilities = pas_backend_vcf_get_static_capabilities;
+ backend_class->start_book_view = pas_backend_vcf_start_book_view;
+ backend_class->cancel_operation = pas_backend_vcf_cancel_operation;
+
+ sync_class->create_contact_sync = pas_backend_vcf_process_create_contact;
+ sync_class->remove_contacts_sync = pas_backend_vcf_process_remove_contacts;
+ sync_class->modify_contact_sync = pas_backend_vcf_process_modify_contact;
+ sync_class->get_contact_sync = pas_backend_vcf_process_get_contact;
+ sync_class->get_contact_list_sync = pas_backend_vcf_process_get_contact_list;
+ sync_class->authenticate_user_sync = pas_backend_vcf_process_authenticate_user;
+ sync_class->get_supported_fields_sync = pas_backend_vcf_process_get_supported_fields;
+
+ object_class->dispose = pas_backend_vcf_dispose;
+}
+
+static void
+pas_backend_vcf_init (PASBackendVCF *backend)
+{
+ PASBackendVCFPrivate *priv;
+
+ priv = g_new0 (PASBackendVCFPrivate, 1);
+ priv->uri = NULL;
+
+ backend->priv = priv;
+}
+
+/**
+ * pas_backend_vcf_get_type:
+ */
+GType
+pas_backend_vcf_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo info = {
+ sizeof (PASBackendVCFClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) pas_backend_vcf_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PASBackendVCF),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pas_backend_vcf_init
+ };
+
+ type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendVCF", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/backend/pas/pas-backend-vcf.h b/addressbook/backend/pas/pas-backend-vcf.h
new file mode 100644
index 0000000000..81c872dcf1
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-vcf.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#ifndef __PAS_BACKEND_VCF_H__
+#define __PAS_BACKEND_VCF_H__
+
+#include "pas-backend-sync.h"
+
+#define PAS_TYPE_BACKEND_VCF (pas_backend_vcf_get_type ())
+#define PAS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_VCF, PASBackendVCF))
+#define PAS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendVCFClass))
+#define PAS_IS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_VCF))
+#define PAS_IS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_VCF))
+#define PAS_BACKEND_VCF_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_VCF, PASBackendVCFClass))
+
+typedef struct _PASBackendVCFPrivate PASBackendVCFPrivate;
+
+typedef struct {
+ PASBackendSync parent_object;
+ PASBackendVCFPrivate *priv;
+} PASBackendVCF;
+
+typedef struct {
+ PASBackendSyncClass parent_class;
+} PASBackendVCFClass;
+
+PASBackend *pas_backend_vcf_new (void);
+GType pas_backend_vcf_get_type (void);
+
+#endif /* ! __PAS_BACKEND_VCF_H__ */
+
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index acc6ed2a2c..076565de07 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -7,12 +7,22 @@
*/
#include <config.h>
+#include <pthread.h>
+#include "pas-book-view.h"
#include "pas-backend.h"
#include "pas-marshal.h"
struct _PASBackendPrivate {
+ GMutex *open_mutex;
+
+ GMutex *clients_mutex;
GList *clients;
- gboolean loaded, writable;
+
+ char *uri;
+ gboolean loaded, writable, removed;
+
+ GMutex *views_mutex;
+ EList *views;
};
/* Signal IDs */
@@ -31,18 +41,25 @@ pas_backend_construct (PASBackend *backend)
return TRUE;
}
-GNOME_Evolution_Addressbook_BookListener_CallStatus
+GNOME_Evolution_Addressbook_CallStatus
pas_backend_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
- g_return_val_if_fail (backend != NULL, FALSE);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
- g_return_val_if_fail (uri != NULL, FALSE);
+ GNOME_Evolution_Addressbook_CallStatus status;
+
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (uri, FALSE);
g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri);
+
+ status = (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri, only_if_exists);
+
+ if (status == GNOME_Evolution_Addressbook_Success)
+ backend->priv->uri = g_strdup (uri);
- return (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri);
+ return status;
}
/**
@@ -56,246 +73,198 @@ pas_backend_load_uri (PASBackend *backend,
const char *
pas_backend_get_uri (PASBackend *backend)
{
- g_return_val_if_fail (backend != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_uri != NULL);
-
- return (* PAS_BACKEND_GET_CLASS (backend)->get_uri) (backend);
+ return backend->priv->uri;
}
-
void
-pas_backend_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+pas_backend_open (PASBackend *backend,
+ PASBook *book,
+ gboolean only_if_exists)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->vcard != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+
+ g_mutex_lock (backend->priv->open_mutex);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->create_card != NULL);
+ if (backend->priv->loaded) {
+ pas_book_respond_open (
+ book, GNOME_Evolution_Addressbook_Success);
- (* PAS_BACKEND_GET_CLASS (backend)->create_card) (backend, book, req);
+ pas_book_report_writable (book, backend->priv->writable);
+ } else {
+ GNOME_Evolution_Addressbook_CallStatus status =
+ pas_backend_load_uri (backend, pas_book_get_uri (book), only_if_exists);
+
+ pas_book_respond_open (book, status);
+
+ if (status == GNOME_Evolution_Addressbook_Success)
+ pas_book_report_writable (book, backend->priv->writable);
+ }
+
+ g_mutex_unlock (backend->priv->open_mutex);
}
void
-pas_backend_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+pas_backend_remove (PASBackend *backend,
+ PASBook *book)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->ids != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_cards != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove);
- (* PAS_BACKEND_GET_CLASS (backend)->remove_cards) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->remove) (backend, book);
}
void
-pas_backend_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+pas_backend_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->vcard != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (vcard);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_card != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->create_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->modify_card) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, vcard);
}
void
-pas_backend_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
+pas_backend_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *id_list)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (id_list);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->check_connection != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_contacts);
- (* PAS_BACKEND_GET_CLASS (backend)->check_connection) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->remove_contacts) (backend, book, id_list);
}
void
-pas_backend_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
- 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 (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (vcard);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_vcard != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->get_vcard) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->modify_contact) (backend, book, vcard);
}
void
-pas_backend_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
+pas_backend_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (id);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_cursor != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->get_cursor) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_contact) (backend, book, id);
}
void
-pas_backend_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
+pas_backend_get_contact_list (PASBackend *backend,
+ PASBook *book,
+ const char *query)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (query);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_book_view != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact_list);
- (* PAS_BACKEND_GET_CLASS (backend)->get_book_view) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_contact_list) (backend, book, query);
}
void
-pas_backend_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
+pas_backend_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book_view && PAS_IS_BOOK_VIEW (book_view));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_completion_view != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->start_book_view);
- (* PAS_BACKEND_GET_CLASS (backend)->get_completion_view) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->start_book_view) (backend, book_view);
}
void
pas_backend_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req)
+ const char *change_id)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->change_id != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (change_id);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes);
- (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, change_id);
}
void
pas_backend_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req)
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (user && passwd && auth_method);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user);
- (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, user, passwd, auth_method);
}
void
pas_backend_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+ PASBook *book)
+
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields);
- (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book);
}
void
pas_backend_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req)
+ PASBook *book)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods);
- (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book);
}
-static void
-process_client_requests (PASBook *book, gpointer user_data)
+GNOME_Evolution_Addressbook_CallStatus
+pas_backend_cancel_operation (PASBackend *backend,
+ PASBook *book)
{
- PASBackend *backend;
- PASRequest *req;
-
- backend = PAS_BACKEND (user_data);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_create_card (backend, book, &req->create);
- break;
-
- case RemoveCards:
- pas_backend_remove_cards (backend, book, &req->remove);
- break;
-
- case ModifyCard:
- pas_backend_modify_card (backend, book, &req->modify);
- break;
-
- case CheckConnection:
- pas_backend_check_connection (backend, book, &req->check_connection);
- break;
-
- case GetVCard:
- pas_backend_get_vcard (backend, book, &req->get_vcard);
- break;
-
- case GetCursor:
- pas_backend_get_cursor (backend, book, &req->get_cursor);
- break;
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
- case GetBookView:
- pas_backend_get_book_view (backend, book, &req->get_book_view);
- break;
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->cancel_operation);
- case GetCompletionView:
- pas_backend_get_completion_view (backend, book, &req->get_completion_view);
- break;
-
- case GetChanges:
- pas_backend_get_changes (backend, book, &req->get_changes);
- break;
-
- case AuthenticateUser:
- pas_backend_authenticate_user (backend, book, &req->auth_user);
- break;
-
- case GetSupportedFields:
- pas_backend_get_supported_fields (backend, book, &req->get_supported_fields);
- break;
-
- case GetSupportedAuthMethods:
- pas_backend_get_supported_auth_methods (backend, book, &req->get_supported_auth_methods);
- break;
- }
-
- pas_book_free_request (req);
+ return (* PAS_BACKEND_GET_CLASS (backend)->cancel_operation) (backend, book);
}
static void
@@ -307,74 +276,82 @@ book_destroy_cb (gpointer data, GObject *where_book_was)
}
static void
+listener_died_cb (gpointer cnx, gpointer user_data)
+{
+ PASBook *book = PAS_BOOK (user_data);
+
+ pas_backend_remove_client (pas_book_get_backend (book), book);
+}
+
+static void
last_client_gone (PASBackend *backend)
{
g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0);
}
-static gboolean
-add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+EList*
+pas_backend_get_book_views (PASBackend *backend)
{
- PASBook *book;
-
- book = pas_book_new (backend, listener);
- if (!book) {
- if (!backend->priv->clients)
- last_client_gone (backend);
-
- return FALSE;
- }
-
- g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
-
- g_signal_connect (book, "requests_queued",
- G_CALLBACK (process_client_requests), backend);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
- backend->priv->clients = g_list_prepend (backend->priv->clients, book);
-
- if (backend->priv->loaded) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
+ return g_object_ref (backend->priv->views);
+}
- pas_book_report_writable (book, backend->priv->writable);
+void
+pas_backend_add_book_view (PASBackend *backend,
+ PASBookView *view)
+{
+ g_mutex_lock (backend->priv->views_mutex);
- bonobo_object_unref (BONOBO_OBJECT (book));
+ e_list_append (backend->priv->views, view);
- return TRUE;
+ g_mutex_unlock (backend->priv->views_mutex);
}
/**
* pas_backend_add_client:
* @backend: An addressbook backend.
- * @listener: Listener for notification to the client.
+ * @book: the corba object representing the client connection.
*
* Adds a client to an addressbook backend.
*
* Return value: TRUE on success, FALSE on failure to add the client.
*/
gboolean
-pas_backend_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+pas_backend_add_client (PASBackend *backend,
+ PASBook *book)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
- g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), FALSE);
+
+ bonobo_object_set_immortal (BONOBO_OBJECT (book), TRUE);
+
+ g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
+
+ ORBit_small_listen_for_broken (pas_book_get_listener (book), G_CALLBACK (listener_died_cb), book);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->add_client != NULL);
+ g_mutex_lock (backend->priv->clients_mutex);
+ backend->priv->clients = g_list_prepend (backend->priv->clients, book);
+ g_mutex_unlock (backend->priv->clients_mutex);
- return PAS_BACKEND_GET_CLASS (backend)->add_client (backend, listener);
+ return TRUE;
}
-static void
-remove_client (PASBackend *backend,
- PASBook *book)
+void
+pas_backend_remove_client (PASBackend *backend,
+ PASBook *book)
{
+ /* XXX this needs a bit more thinking wrt the mutex - we
+ should be holding it when we check to see if clients is
+ NULL */
+
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+
/* Disconnect */
+ g_mutex_lock (backend->priv->clients_mutex);
backend->priv->clients = g_list_remove (backend->priv->clients, book);
+ g_mutex_unlock (backend->priv->clients_mutex);
/* When all clients go away, notify the parent factory about it so that
* it may decide whether to kill the backend or not.
@@ -383,25 +360,12 @@ remove_client (PASBackend *backend,
last_client_gone (backend);
}
-void
-pas_backend_remove_client (PASBackend *backend,
- PASBook *book)
-{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
-
- g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_client != NULL);
-
- PAS_BACKEND_GET_CLASS (backend)->remove_client (backend, book);
-}
-
char *
pas_backend_get_static_capabilities (PASBackend *backend)
{
- g_return_val_if_fail (backend != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities);
return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend);
}
@@ -409,7 +373,7 @@ pas_backend_get_static_capabilities (PASBackend *backend)
gboolean
pas_backend_is_loaded (PASBackend *backend)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
return backend->priv->loaded;
}
@@ -417,7 +381,7 @@ pas_backend_is_loaded (PASBackend *backend)
void
pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
backend->priv->loaded = is_loaded;
}
@@ -425,7 +389,7 @@ pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded)
gboolean
pas_backend_is_writable (PASBackend *backend)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
return backend->priv->writable;
}
@@ -433,18 +397,175 @@ pas_backend_is_writable (PASBackend *backend)
void
pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
backend->priv->writable = is_writable;
}
+gboolean
+pas_backend_is_removed (PASBackend *backend)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+
+ return backend->priv->removed;
+}
+
+void
+pas_backend_set_is_removed (PASBackend *backend, gboolean is_removed)
+{
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+
+ backend->priv->removed = is_removed;
+}
+
+
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_add_new (const char *vcard)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactAdded;
+ new_change->_u.add_vcard = CORBA_string_dup (vcard);
+
+ return new_change;
+}
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_modify_new (const char *vcard)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactModified;
+ new_change->_u.mod_vcard = CORBA_string_dup (vcard);
+
+ return new_change;
+}
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_delete_new (const char *id)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactDeleted;
+ new_change->_u.del_id = CORBA_string_dup (id);
+
+ return new_change;
+}
+
+
+
+static void
+pas_backend_foreach_view (PASBackend *backend,
+ void (*callback) (PASBookView *, gpointer),
+ gpointer user_data)
+{
+ EList *views;
+ PASBookView *view;
+ EIterator *iter;
+
+ views = pas_backend_get_book_views (backend);
+ iter = e_list_get_iterator (views);
+
+ while (e_iterator_is_valid (iter)) {
+ view = (PASBookView*)e_iterator_get (iter);
+
+ bonobo_object_ref (view);
+ callback (view, user_data);
+ bonobo_object_unref (view);
+
+ e_iterator_next (iter);
+ }
+
+ g_object_unref (iter);
+ g_object_unref (views);
+}
+
+
+static void
+view_notify_update (PASBookView *view, gpointer contact)
+{
+ pas_book_view_notify_update (view, contact);
+}
+
+/**
+ * pas_backend_notify_update:
+ * @backend: an addressbook backend
+ * @contact: a new or modified contact
+ *
+ * Notifies all of @backend's book views about the new or modified
+ * contacts @contact.
+ *
+ * pas_book_respond_create() and pas_book_respond_modify() call this
+ * function for you. You only need to call this from your backend if
+ * contacts are created or modified by another (non-PAS-using) client.
+ **/
+void
+pas_backend_notify_update (PASBackend *backend, EContact *contact)
+{
+ pas_backend_foreach_view (backend, view_notify_update, contact);
+}
+
+
+static void
+view_notify_remove (PASBookView *view, gpointer id)
+{
+ pas_book_view_notify_remove (view, id);
+}
+
+/**
+ * pas_backend_notify_remove:
+ * @backend: an addressbook backend
+ * @id: a contact id
+ *
+ * Notifies all of @backend's book views that the contact with UID
+ * @id has been removed.
+ *
+ * pas_book_respond_remove_contacts() calls this function for you. You
+ * only need to call this from your backend if contacts are removed by
+ * another (non-PAS-using) client.
+ **/
+void
+pas_backend_notify_remove (PASBackend *backend, const char *id)
+{
+ pas_backend_foreach_view (backend, view_notify_remove, (gpointer)id);
+}
+
+
+static void
+view_notify_complete (PASBookView *view, gpointer unused)
+{
+ pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
+}
+
+/**
+ * pas_backend_notify_complete:
+ * @backend: an addressbook backend
+ *
+ * Notifies all of @backend's book views that the current set of
+ * notifications is complete; use this after a series of
+ * pas_backend_notify_update() and pas_backend_notify_remove() calls.
+ **/
+void
+pas_backend_notify_complete (PASBackend *backend)
+{
+ pas_backend_foreach_view (backend, view_notify_complete, NULL);
+}
+
+
+
static void
pas_backend_init (PASBackend *backend)
{
PASBackendPrivate *priv;
priv = g_new0 (PASBackendPrivate, 1);
+ priv->uri = NULL;
priv->clients = NULL;
+ priv->views = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL);
+ priv->open_mutex = g_mutex_new ();
+ priv->clients_mutex = g_mutex_new ();
+ priv->views_mutex = g_mutex_new ();
backend->priv = priv;
}
@@ -458,8 +579,20 @@ pas_backend_dispose (GObject *object)
if (backend->priv) {
g_list_free (backend->priv->clients);
- g_free (backend->priv);
+ if (backend->priv->uri)
+ g_free (backend->priv->uri);
+
+ if (backend->priv->views) {
+ g_object_unref (backend->priv->views);
+ backend->priv->views = NULL;
+ }
+
+ g_mutex_free (backend->priv->open_mutex);
+ g_mutex_free (backend->priv->clients_mutex);
+ g_mutex_free (backend->priv->views_mutex);
+
+ g_free (backend->priv);
backend->priv = NULL;
}
@@ -475,9 +608,6 @@ pas_backend_class_init (PASBackendClass *klass)
object_class = (GObjectClass *) klass;
- klass->add_client = add_client;
- klass->remove_client = remove_client;
-
object_class->dispose = pas_backend_dispose;
pas_backend_signals[LAST_CLIENT_GONE] =
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index b33518116e..41f6542213 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -25,6 +25,8 @@
#include <glib.h>
#include <glib-object.h>
#include <pas/addressbook.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BACKEND (pas_backend_get_type ())
#define PAS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND, PASBackend))
@@ -33,7 +35,6 @@
#define PAS_IS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND))
#define PAS_BACKEND_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND, PASBackendClass))
-typedef struct _PASBackend PASBackend;
typedef struct _PASBackendPrivate PASBackendPrivate;
#include <pas/pas-book.h>
@@ -43,44 +44,49 @@ struct _PASBackend {
PASBackendPrivate *priv;
};
-typedef struct {
+struct _PASBackendClass {
GObjectClass parent_class;
/* Virtual methods */
- GNOME_Evolution_Addressbook_BookListener_CallStatus (*load_uri) (PASBackend *backend, const char *uri);
- const char *(* get_uri) (PASBackend *backend);
- gboolean (*add_client) (PASBackend *backend, GNOME_Evolution_Addressbook_BookListener listener);
- void (*remove_client) (PASBackend *backend, PASBook *book);
+ GNOME_Evolution_Addressbook_CallStatus (*load_uri) (PASBackend *backend, const char *uri, gboolean only_if_exists);
+ void (*remove) (PASBackend *backend, PASBook *book);
char *(*get_static_capabilities) (PASBackend *backend);
- 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);
- void (*get_book_view) (PASBackend *backend, PASBook *book, PASGetBookViewRequest *req);
- void (*get_completion_view) (PASBackend *backend, PASBook *book, PASGetCompletionViewRequest *req);
- void (*get_changes) (PASBackend *backend, PASBook *book, PASGetChangesRequest *req);
- void (*authenticate_user) (PASBackend *backend, PASBook *book, PASAuthenticateUserRequest *req);
- void (*get_supported_fields) (PASBackend *backend, PASBook *book, PASGetSupportedFieldsRequest *req);
- void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book, PASGetSupportedAuthMethodsRequest *req);
+ void (*create_contact) (PASBackend *backend, PASBook *book, const char *vcard);
+ void (*remove_contacts) (PASBackend *backend, PASBook *book, GList *id_list);
+ void (*modify_contact) (PASBackend *backend, PASBook *book, const char *vcard);
+ void (*get_contact) (PASBackend *backend, PASBook *book, const char *id);
+ void (*get_contact_list) (PASBackend *backend, PASBook *book, const char *query);
+ void (*start_book_view) (PASBackend *backend, PASBookView *book_view);
+ void (*get_changes) (PASBackend *backend, PASBook *book, const char *change_id);
+ void (*authenticate_user) (PASBackend *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method);
+ void (*get_supported_fields) (PASBackend *backend, PASBook *book);
+ void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book);
+ GNOME_Evolution_Addressbook_CallStatus (*cancel_operation) (PASBackend *backend, PASBook *book);
/* Notification signals */
void (* last_client_gone) (PASBackend *backend);
-} PASBackendClass;
+
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+};
typedef PASBackend * (*PASBackendFactoryFn) (void);
gboolean pas_backend_construct (PASBackend *backend);
-GNOME_Evolution_Addressbook_BookListener_CallStatus
+GNOME_Evolution_Addressbook_CallStatus
pas_backend_load_uri (PASBackend *backend,
- const char *uri);
+ const char *uri,
+ gboolean only_if_exists);
const char *pas_backend_get_uri (PASBackend *backend);
gboolean pas_backend_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener);
+ PASBook *book);
void pas_backend_remove_client (PASBackend *backend,
PASBook *book);
char *pas_backend_get_static_capabilities (PASBackend *backend);
@@ -89,42 +95,56 @@ gboolean pas_backend_is_loaded (PASBackend *backen
gboolean pas_backend_is_writable (PASBackend *backend);
-void pas_backend_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req);
-void pas_backend_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req);
-void pas_backend_modify_card (PASBackend *backend,
+gboolean pas_backend_is_removed (PASBackend *backend);
+
+void pas_backend_open (PASBackend *backend,
PASBook *book,
- PASModifyCardRequest *req);
-void pas_backend_check_connection (PASBackend *backend,
+ gboolean only_if_exists);
+void pas_backend_remove (PASBackend *backend,
+ PASBook *book);
+void pas_backend_create_contact (PASBackend *backend,
PASBook *book,
- PASCheckConnectionRequest *req);
-void pas_backend_get_vcard (PASBackend *backend,
+ const char *vcard);
+void pas_backend_remove_contacts (PASBackend *backend,
PASBook *book,
- PASGetVCardRequest *req);
-void pas_backend_get_cursor (PASBackend *backend,
+ GList *id_list);
+void pas_backend_modify_contact (PASBackend *backend,
PASBook *book,
- PASGetCursorRequest *req);
-void pas_backend_get_book_view (PASBackend *backend,
+ const char *vcard);
+void pas_backend_get_contact (PASBackend *backend,
PASBook *book,
- PASGetBookViewRequest *req);
-void pas_backend_get_completion_view (PASBackend *backend,
+ const char *id);
+void pas_backend_get_contact_list (PASBackend *backend,
PASBook *book,
- PASGetCompletionViewRequest *req);
+ const char *query);
void pas_backend_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req);
+ const char *change_id);
void pas_backend_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req);
+ const char *user,
+ const char *passwd,
+ const char *auth_method);
void pas_backend_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req);
+ PASBook *book);
void pas_backend_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req);
+ PASBook *book);
+GNOME_Evolution_Addressbook_CallStatus pas_backend_cancel_operation (PASBackend *backend,
+ PASBook *book);
+
+void pas_backend_start_book_view (PASBackend *backend,
+ PASBookView *view);
+
+void pas_backend_add_book_view (PASBackend *backend,
+ PASBookView *view);
+
+EList *pas_backend_get_book_views (PASBackend *backend);
+
+void pas_backend_notify_update (PASBackend *backend,
+ EContact *contact);
+void pas_backend_notify_remove (PASBackend *backend,
+ const char *id);
+void pas_backend_notify_complete (PASBackend *backend);
GType pas_backend_get_type (void);
@@ -135,6 +155,13 @@ void pas_backend_set_is_loaded (PASBackend *backen
gboolean is_loaded);
void pas_backend_set_is_writable (PASBackend *backend,
gboolean is_writable);
+void pas_backend_set_is_removed (PASBackend *backend,
+ gboolean is_removed);
+
+/* useful for implementing _get_changes in backends */
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_add_new (const char *vcard);
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_modify_new (const char *vcard);
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_delete_new (const char *id);
#endif /* ! __PAS_BACKEND_H__ */
diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c
index 2d6ed1e65b..34e97aa780 100644
--- a/addressbook/backend/pas/pas-book-factory.c
+++ b/addressbook/backend/pas/pas-book-factory.c
@@ -8,6 +8,7 @@
*/
#include <config.h>
+#include <pthread.h>
#include <string.h>
#include "addressbook.h"
@@ -15,21 +16,22 @@
#include "pas-marshal.h"
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-arg.h>
#define DEFAULT_PAS_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory"
static BonoboObjectClass *pas_book_factory_parent_class;
typedef struct {
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
+ char *uri;
+ GNOME_Evolution_Addressbook_BookListener listener;
} PASBookFactoryQueuedRequest;
struct _PASBookFactoryPrivate {
- gint idle_id;
+ GMutex *map_mutex;
+
GHashTable *backends;
GHashTable *active_server_map;
- GList *queued_requests;
/* OAFIID of the factory */
char *iid;
@@ -108,10 +110,16 @@ pas_book_factory_register_backend (PASBookFactory *factory,
int
pas_book_factory_get_n_backends (PASBookFactory *factory)
{
+ int n_backends;
+
g_return_val_if_fail (factory != NULL, -1);
g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), -1);
- return g_hash_table_size (factory->priv->active_server_map);
+ g_mutex_lock (factory->priv->map_mutex);
+ n_backends = g_hash_table_size (factory->priv->active_server_map);
+ g_mutex_unlock (factory->priv->map_mutex);
+
+ return n_backends;
}
static void
@@ -131,10 +139,11 @@ pas_book_factory_dump_active_backends (PASBookFactory *factory)
{
g_message ("Active PAS backends");
+ g_mutex_lock (factory->priv->map_mutex);
g_hash_table_foreach (factory->priv->active_server_map,
dump_active_server_map_entry,
NULL);
-
+ g_mutex_unlock (factory->priv->map_mutex);
}
/* Callback used when a backend loses its last connected client */
@@ -154,6 +163,8 @@ backend_last_client_gone_cb (PASBackend *backend, gpointer data)
gboolean result;
char *orig_uri;
+ g_mutex_lock (factory->priv->map_mutex);
+
result = g_hash_table_lookup_extended (factory->priv->active_server_map, uri,
&orig_key, NULL);
g_assert (result != FALSE);
@@ -165,13 +176,17 @@ backend_last_client_gone_cb (PASBackend *backend, gpointer data)
g_object_unref (backend);
- /* Notify upstream if there are no more backends */
+ g_mutex_unlock (factory->priv->map_mutex);
}
- if (g_hash_table_size (factory->priv->active_server_map) == 0)
+ if (g_hash_table_size (factory->priv->active_server_map) == 0) {
+ /* Notify upstream if there are no more backends */
g_signal_emit (G_OBJECT (factory), factory_signals[LAST_BOOK_GONE], 0);
+ }
}
+
+
static PASBackendFactoryFn
pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
const char *uri)
@@ -203,52 +218,16 @@ pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
}
static PASBackend *
-pas_book_factory_launch_backend (PASBookFactory *factory,
- GNOME_Evolution_Addressbook_BookListener listener,
- const char *uri)
+pas_book_factory_launch_backend (PASBookFactory *factory,
+ PASBackendFactoryFn backend_factory,
+ GNOME_Evolution_Addressbook_BookListener listener,
+ const char *uri)
{
- PASBackendFactoryFn backend_factory;
PASBackend *backend;
- backend_factory = pas_book_factory_lookup_backend_factory (
- factory, uri);
-
- if (!backend_factory) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_launch_backend(): could not notify "
- "the listener");
-
- CORBA_exception_free (&ev);
- return NULL;
- }
-
backend = (* backend_factory) ();
- if (!backend) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_launch_backend(): could not notify "
- "the listener");
-
- CORBA_exception_free (&ev);
+ if (!backend)
return NULL;
- }
g_hash_table_insert (factory->priv->active_server_map,
g_strdup (uri),
@@ -261,154 +240,63 @@ pas_book_factory_launch_backend (PASBookFactory *factory,
return backend;
}
-static void
-pas_book_factory_process_request (PASBookFactory *factory,
- PASBookFactoryQueuedRequest *request)
+static GNOME_Evolution_Addressbook_Book
+impl_GNOME_Evolution_Addressbook_BookFactory_getBook (PortableServer_Servant servant,
+ const CORBA_char *uri,
+ const GNOME_Evolution_Addressbook_BookListener listener,
+ CORBA_Environment *ev)
{
+ PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant));
PASBackend *backend;
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
- CORBA_Environment ev;
+ PASBook *book;
- uri = request->uri;
- listener = request->listener;
- g_free (request);
+ printf ("impl_GNOME_Evolution_Addressbook_BookFactory_getBook\n");
/* Look up the backend and create one if needed */
+ g_mutex_lock (factory->priv->map_mutex);
backend = g_hash_table_lookup (factory->priv->active_server_map, uri);
if (!backend) {
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
-
- backend = pas_book_factory_launch_backend (factory, listener, uri);
- if (!backend)
- goto out;
+ PASBackendFactoryFn backend_factory;
- status = pas_backend_load_uri (backend, uri);
- if (status != GNOME_Evolution_Addressbook_BookListener_Success) {
- /* tell the listener that we failed to open the book */
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener, status,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_open: Exception "
- "responding to BookListener!\n");
- }
+ backend_factory = pas_book_factory_lookup_backend_factory (factory, uri);
+
+ if (backend_factory == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
+ NULL);
- CORBA_exception_free (&ev);
-
- backend_last_client_gone_cb (backend, factory);
+ g_mutex_unlock (factory->priv->map_mutex);
- goto out;
+ return CORBA_OBJECT_NIL;
}
- pas_backend_add_client (backend, listener);
-
- goto out;
+ backend = pas_book_factory_launch_backend (factory, backend_factory, listener, uri);
}
- pas_backend_add_client (backend, listener);
+ if (backend) {
+ GNOME_Evolution_Addressbook_BookListener listener_copy;
- out:
- g_free (uri);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (listener, &ev);
+ listener_copy = bonobo_object_dup_ref (listener, NULL);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_process_request(): could not release the listener");
+ g_mutex_unlock (factory->priv->map_mutex);
- CORBA_exception_free (&ev);
-}
+ book = pas_book_new (backend, uri, listener);
-static gboolean
-pas_book_factory_process_queue (PASBookFactory *factory)
-{
- /* Process pending Book-creation requests. */
- if (factory->priv->queued_requests != NULL) {
- PASBookFactoryQueuedRequest *request;
- GList *l;
+ pas_backend_add_client (backend, book);
- l = factory->priv->queued_requests;
- request = l->data;
-
- pas_book_factory_process_request (factory, request);
-
- factory->priv->queued_requests = g_list_remove_link (
- factory->priv->queued_requests, l);
- g_list_free_1 (l);
- }
-
- if (factory->priv->queued_requests == NULL) {
-
- factory->priv->idle_id = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-pas_book_factory_queue_request (PASBookFactory *factory,
- const char *uri,
- const GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBookFactoryQueuedRequest *request;
- GNOME_Evolution_Addressbook_BookListener listener_copy;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- listener_copy = CORBA_Object_duplicate (listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("PASBookFactory: Could not duplicate BookListener!\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- request = g_new0 (PASBookFactoryQueuedRequest, 1);
- request->listener = listener_copy;
- request->uri = g_strdup (uri);
-
- factory->priv->queued_requests =
- g_list_prepend (factory->priv->queued_requests, request);
-
- if (! factory->priv->idle_id) {
- factory->priv->idle_id =
- g_idle_add ((GSourceFunc) pas_book_factory_process_queue, factory);
+ return bonobo_object_corba_objref (BONOBO_OBJECT (book));
}
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_BookFactory_openBook (PortableServer_Servant servant,
- const CORBA_char *uri,
- const GNOME_Evolution_Addressbook_BookListener listener,
- CORBA_Environment *ev)
-{
- PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant));
- PASBackendFactoryFn backend_factory;
-
- backend_factory = pas_book_factory_lookup_backend_factory (factory, uri);
-
- if (backend_factory == NULL) {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported,
- CORBA_OBJECT_NIL,
- ev);
-
- return;
+ else {
+ /* probably need a more descriptive exception here */
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
+ NULL);
+ g_mutex_unlock (factory->priv->map_mutex);
+
+ return CORBA_OBJECT_NIL;
}
-
- pas_book_factory_queue_request (factory, uri, listener);
}
static void
@@ -425,7 +313,9 @@ pas_book_factory_new (void)
{
PASBookFactory *factory;
- factory = g_object_new (PAS_TYPE_BOOK_FACTORY, NULL);
+ factory = g_object_new (PAS_TYPE_BOOK_FACTORY,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
pas_book_factory_construct (factory);
@@ -483,9 +373,9 @@ pas_book_factory_init (PASBookFactory *factory)
{
factory->priv = g_new0 (PASBookFactoryPrivate, 1);
+ factory->priv->map_mutex = g_mutex_new();
factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal);
factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal);
- factory->priv->queued_requests = NULL;
factory->priv->registered = FALSE;
}
@@ -518,22 +408,8 @@ pas_book_factory_dispose (GObject *object)
if (factory->priv) {
PASBookFactoryPrivate *priv = factory->priv;
- GList *l;
- for (l = priv->queued_requests; l != NULL; l = l->next) {
- PASBookFactoryQueuedRequest *request = l->data;
- CORBA_Environment ev;
-
- g_free (request->uri);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (request->listener, &ev);
- CORBA_exception_free (&ev);
-
- g_free (request);
- }
- g_list_free (priv->queued_requests);
- priv->queued_requests = NULL;
+ g_mutex_free (priv->map_mutex);
g_hash_table_foreach (priv->active_server_map,
free_active_server_map_entry,
@@ -585,7 +461,7 @@ pas_book_factory_class_init (PASBookFactoryClass *klass)
epv = &klass->epv;
- epv->openBook = impl_GNOME_Evolution_Addressbook_BookFactory_openBook;
+ epv->getBook = impl_GNOME_Evolution_Addressbook_BookFactory_getBook;
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
index fce4173f0f..712997d258 100644
--- a/addressbook/backend/pas/pas-book-view.c
+++ b/addressbook/backend/pas/pas-book-view.c
@@ -6,158 +6,266 @@
*/
#include <config.h>
+#include <string.h>
#include <glib.h>
#include <bonobo/bonobo-main.h>
+#include "pas-backend.h"
+#include "pas-backend-card-sexp.h"
#include "pas-book-view.h"
static BonoboObjectClass *pas_book_view_parent_class;
struct _PASBookViewPrivate {
GNOME_Evolution_Addressbook_BookViewListener listener;
+
+#define INITIAL_THRESHOLD 20
+ GMutex *pending_mutex;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
+ int next_threshold;
+ int threshold_max;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard changes;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId removes;
+
+ PASBackend *backend;
+ char *card_query;
+ PASBackendCardSExp *card_sexp;
+ GHashTable *ids;
};
-/**
- * pas_book_view_notify_change:
- */
-void
-pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards)
+static void
+send_pending_adds (PASBookView *book_view, gboolean reset)
{
CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+
+ adds = &book_view->priv->adds;
+ if (adds->_length == 0)
+ return;
- length = g_list_length((GList *) cards);
+ CORBA_exception_init (&ev);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsAdded (
+ book_view->priv->listener, adds, &ev);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_adds: Exception signaling BookViewListener!\n");
}
+ CORBA_exception_free (&ev);
+
+ CORBA_free (adds->_buffer);
+ adds->_buffer = NULL;
+ adds->_maximum = 0;
+ adds->_length = 0;
+
+ if (reset)
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+}
+
+static void
+send_pending_changes (PASBookView *book_view)
+{
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ changes = &book_view->priv->changes;
+ if (changes->_length == 0)
+ return;
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardChanged (
- book_view->priv->listener, &card_sequence, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsChanged (
+ book_view->priv->listener, changes, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_change: Exception signaling BookViewListener!\n");
+ g_warning ("send_pending_changes: Exception signaling BookViewListener!\n");
}
CORBA_exception_free (&ev);
- CORBA_free(card_sequence._buffer);
+ CORBA_free (changes->_buffer);
+ changes->_buffer = NULL;
+ changes->_maximum = 0;
+ changes->_length = 0;
}
-void
-pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card)
+static void
+send_pending_removes (PASBookView *book_view)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_change(book_view, list);
- g_list_free(list);
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *removes;
+
+ removes = &book_view->priv->removes;
+ if (removes->_length == 0)
+ return;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsRemoved (
+ book_view->priv->listener, removes, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_removes: Exception signaling BookViewListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+
+ CORBA_free (removes->_buffer);
+ removes->_buffer = NULL;
+ removes->_maximum = 0;
+ removes->_length = 0;
}
-/**
- * pas_book_view_notify_remove:
- */
-void
-pas_book_view_notify_remove_1 (PASBookView *book_view,
- const char *id)
+#define MAKE_REALLOC(type) \
+static void \
+CORBA_sequence_ ## type ## _realloc (CORBA_sequence_ ## type *seq, \
+ CORBA_unsigned_long new_max) \
+{ \
+ type *new_buf; \
+ \
+ new_buf = CORBA_sequence_ ## type ## _allocbuf (new_max); \
+ memcpy (new_buf, seq->_buffer, seq->_maximum * sizeof (type)); \
+ CORBA_free (seq->_buffer); \
+ seq->_buffer = new_buf; \
+ seq->_maximum = new_max; \
+}
+
+MAKE_REALLOC (GNOME_Evolution_Addressbook_VCard)
+MAKE_REALLOC (GNOME_Evolution_Addressbook_ContactId)
+
+static void
+notify_change (PASBookView *book_view, const char *vcard)
{
- GList *ids = NULL;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_removes (book_view);
- ids = g_list_prepend (ids, (char*)id);
+ changes = &book_view->priv->changes;
- pas_book_view_notify_remove (book_view, ids);
+ if (changes->_length == changes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard_realloc (
+ changes, 2 * (changes->_maximum + 1));
+ }
- g_list_free (ids);
+ changes->_buffer[changes->_length++] = CORBA_string_dup (vcard);
}
-void
-pas_book_view_notify_remove (PASBookView *book_view,
- const GList *ids)
+static void
+notify_remove (PASBookView *book_view, const char *id)
{
- GNOME_Evolution_Addressbook_CardIdList idlist;
- CORBA_Environment ev;
- const GList *l;
- int num_ids, i;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId *removes;
- CORBA_exception_init (&ev);
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
- 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;
+ removes = &book_view->priv->removes;
- for (l = ids, i = 0; l; l=l->next, i ++) {
- idlist._buffer[i] = CORBA_string_dup (l->data);
+ if (removes->_length == removes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_realloc (
+ removes, 2 * (removes->_maximum + 1));
}
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardsRemoved (
- book_view->priv->listener, &idlist, &ev);
+ removes->_buffer[removes->_length++] = CORBA_string_dup (id);
+ g_hash_table_remove (book_view->priv->ids, id);
+}
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n");
- }
+static void
+notify_add (PASBookView *book_view, const char *id, const char *vcard)
+{
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+ PASBookViewPrivate *priv = book_view->priv;
- CORBA_free(idlist._buffer);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
- CORBA_exception_free (&ev);
+ adds = &priv->adds;
+
+ if (adds->_length == adds->_maximum) {
+ send_pending_adds (book_view, FALSE);
+
+ adds->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf (priv->next_threshold);
+ adds->_maximum = priv->next_threshold;
+
+ if (priv->next_threshold < priv->threshold_max) {
+ priv->next_threshold = MIN (2 * priv->next_threshold,
+ priv->threshold_max);
+ }
+ }
+
+ adds->_buffer[adds->_length++] = CORBA_string_dup (vcard);
+ g_hash_table_insert (book_view->priv->ids, g_strdup (id),
+ GUINT_TO_POINTER (1));
}
/**
- * pas_book_view_notify_add:
+ * pas_book_view_notify_update:
*/
void
-pas_book_view_notify_add (PASBookView *book_view,
- const GList *cards)
+pas_book_view_notify_update (PASBookView *book_view,
+ EContact *contact)
{
- CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ gboolean currently_in_view, want_in_view;
+ const char *id;
+ char *vcard;
- length = g_list_length((GList *)cards);
+ g_mutex_lock (book_view->priv->pending_mutex);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ id = e_contact_get_const (contact, E_CONTACT_UID);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
- }
+ currently_in_view =
+ g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+ want_in_view = pas_backend_card_sexp_match_contact (
+ book_view->priv->card_sexp, contact);
- CORBA_exception_init (&ev);
+ if (want_in_view) {
+ vcard = e_vcard_to_string (E_VCARD (contact),
+ EVC_FORMAT_VCARD_30);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardAdded (
- book_view->priv->listener, &card_sequence, &ev);
+ if (currently_in_view)
+ notify_change (book_view, vcard);
+ else
+ notify_add (book_view, id, vcard);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_add: Exception signaling BookViewListener!\n");
+ g_free (vcard);
+ } else {
+ if (currently_in_view)
+ pas_book_view_notify_remove (book_view, id);
+ /* else nothing; we're removing a card that wasn't there */
}
- CORBA_exception_free (&ev);
-
- CORBA_free(card_sequence._buffer);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+/**
+ * pas_book_view_notify_remove:
+ */
void
-pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card)
+pas_book_view_notify_remove (PASBookView *book_view,
+ const char *id)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_add(book_view, list);
- g_list_free(list);
+ g_mutex_lock (book_view->priv->pending_mutex);
+ notify_remove (book_view, id);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+
void
pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
+ g_mutex_lock (book_view->priv->pending_mutex);
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
+
+ g_mutex_unlock (book_view->priv->pending_mutex);
+
CORBA_exception_init (&ev);
GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete (
@@ -178,8 +286,8 @@ pas_book_view_notify_status_message (PASBookView *book_view,
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyStatusMessage (
- book_view->priv->listener, message, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyProgress (
+ book_view->priv->listener, message, 0, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n");
@@ -190,7 +298,10 @@ pas_book_view_notify_status_message (PASBookView *book_view,
static void
pas_book_view_construct (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener listener)
+ PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookViewPrivate *priv;
CORBA_Environment ev;
@@ -202,29 +313,70 @@ pas_book_view_construct (PASBookView *book_view,
CORBA_exception_init (&ev);
- bonobo_object_dup_ref (listener, &ev);
+ priv->listener = CORBA_Object_duplicate (listener, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("Unable to duplicate & ref listener object in pas-book-view.c\n");
+ g_warning("Unable to duplicate listener object in pas-book-view.c\n");
CORBA_exception_free (&ev);
return;
}
CORBA_exception_free (&ev);
- priv->listener = listener;
+ priv->backend = backend;
+ priv->card_query = g_strdup (card_query);
+ priv->card_sexp = card_sexp;
+}
+
+/**
+ * pas_book_view_new:
+ */
+static void
+impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBookView *view = PAS_BOOK_VIEW (bonobo_object (servant));
+
+ pas_backend_start_book_view (pas_book_view_get_backend (view), view);
+}
+
+/**
+ * pas_book_view_get_card_query
+ */
+const char*
+pas_book_view_get_card_query (PASBookView *book_view)
+{
+ return book_view->priv->card_query;
+}
+
+/**
+ * pas_book_view_get_card_sexp
+ */
+PASBackendCardSExp*
+pas_book_view_get_card_sexp (PASBookView *book_view)
+{
+ return book_view->priv->card_sexp;
+}
+
+PASBackend*
+pas_book_view_get_backend (PASBookView *book_view)
+{
+ return book_view->priv->backend;
}
/**
* pas_book_view_new:
*/
PASBookView *
-pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener)
+pas_book_view_new (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookView *book_view;
book_view = g_object_new (PAS_TYPE_BOOK_VIEW, NULL);
- pas_book_view_construct (book_view, listener);
+ pas_book_view_construct (book_view, backend, listener, card_query, card_sexp);
return book_view;
}
@@ -237,6 +389,19 @@ pas_book_view_dispose (GObject *object)
if (book_view->priv) {
bonobo_object_release_unref (book_view->priv->listener, NULL);
+ if (book_view->priv->adds._buffer)
+ CORBA_free (book_view->priv->adds._buffer);
+ if (book_view->priv->changes._buffer)
+ CORBA_free (book_view->priv->changes._buffer);
+ if (book_view->priv->removes._buffer)
+ CORBA_free (book_view->priv->removes._buffer);
+
+ g_free (book_view->priv->card_query);
+ g_object_unref (book_view->priv->card_sexp);
+
+ g_mutex_free (book_view->priv->pending_mutex);
+ book_view->priv->pending_mutex = NULL;
+
g_free (book_view->priv);
book_view->priv = NULL;
}
@@ -249,17 +414,30 @@ static void
pas_book_view_class_init (PASBookViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ POA_GNOME_Evolution_Addressbook_BookView__epv *epv;
pas_book_view_parent_class = g_type_class_peek_parent (klass);
object_class->dispose = pas_book_view_dispose;
+
+ epv = &klass->epv;
+
+ epv->start = impl_GNOME_Evolution_Addressbook_BookView_start;
+
}
static void
pas_book_view_init (PASBookView *book_view)
{
- book_view->priv = g_new0 (PASBookViewPrivate, 1);
- book_view->priv->listener = CORBA_OBJECT_NIL;
+ book_view->priv = g_new0 (PASBookViewPrivate, 1);
+
+ book_view->priv->pending_mutex = g_mutex_new();
+
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+ book_view->priv->threshold_max = 3000;
+
+ book_view->priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h
index dd6c74c596..0cacab6bf0 100644
--- a/addressbook/backend/pas/pas-book-view.h
+++ b/addressbook/backend/pas/pas-book-view.h
@@ -16,6 +16,8 @@
#include <pas/addressbook.h>
#include <glib.h>
#include <glib-object.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BOOK_VIEW (pas_book_view_get_type ())
#define PAS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_VIEW, PASBookView))
@@ -24,8 +26,6 @@
#define PAS_IS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_VIEW))
#define PAS_BOOK_VIEW_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_VIEW, PASBookView))
-typedef struct _PASBookView PASBookView;
-typedef struct _PASBookViewClass PASBookViewClass;
typedef struct _PASBookViewPrivate PASBookViewPrivate;
struct _PASBookView {
@@ -40,25 +40,24 @@ struct _PASBookViewClass {
};
-PASBookView *pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener);
+PASBookView *pas_book_view_new (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp);
-void pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards);
-void pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card);
+const char* pas_book_view_get_card_query (PASBookView *book_view);
+PASBackendCardSExp* pas_book_view_get_card_sexp (PASBookView *book_view);
+PASBackend* pas_book_view_get_backend (PASBookView *book_view);
+
+void pas_book_view_notify_update (PASBookView *book_view,
+ EContact *contact);
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);
-void pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card);
void pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus);
+ GNOME_Evolution_Addressbook_CallStatus);
void pas_book_view_notify_status_message (PASBookView *book_view,
const char *message);
-GType pas_book_view_get_type (void);
+GType pas_book_view_get_type (void);
#endif /* ! __PAS_BOOK_VIEW_H__ */
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
index dc626e59e1..7b6e0c9a2b 100644
--- a/addressbook/backend/pas/pas-book.c
+++ b/addressbook/backend/pas/pas-book.c
@@ -7,261 +7,68 @@
#include <config.h>
#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-arg.h>
#include "e-util/e-list.h"
+#include "ebook/e-contact.h"
+#include "pas-book-view.h"
#include "pas-backend.h"
+#include "pas-backend-card-sexp.h"
#include "pas-marshal.h"
static BonoboObjectClass *pas_book_parent_class;
POA_GNOME_Evolution_Addressbook_Book__vepv pas_book_vepv;
-enum {
- REQUESTS_QUEUED,
- LAST_SIGNAL
-};
-
-static guint pas_book_signals [LAST_SIGNAL];
-
struct _PASBookPrivate {
- PASBackend *backend;
+ PASBackend *backend;
GNOME_Evolution_Addressbook_BookListener listener;
-
- GList *request_queue;
- gint timeout_id;
-
- guint timeout_lock : 1;
+ char *uri;
};
-static gboolean
-pas_book_check_queue (PASBook *book)
-{
- if (book->priv->timeout_lock)
- return TRUE;
-
- book->priv->timeout_lock = TRUE;
-
- if (book->priv->request_queue != NULL) {
- g_signal_emit (book, pas_book_signals [REQUESTS_QUEUED], 0);
- }
-
- if (book->priv->request_queue == NULL) {
- book->priv->timeout_id = 0;
- book->priv->timeout_lock = FALSE;
- bonobo_object_unref (BONOBO_OBJECT (book));
- return FALSE;
- }
-
- book->priv->timeout_lock = FALSE;
-
- return TRUE;
-}
-
-static void
-pas_book_queue_request (PASBook *book, PASRequest *req)
-{
- book->priv->request_queue =
- g_list_append (book->priv->request_queue, req);
-
- if (book->priv->timeout_id == 0) {
- bonobo_object_ref (BONOBO_OBJECT (book));
- book->priv->timeout_id = g_timeout_add (20, (GSourceFunc) pas_book_check_queue, book);
- }
-}
-
-static void
-pas_book_queue_create_card (PASBook *book, const char *vcard)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = CreateCard;
- req->create.vcard = g_strdup (vcard);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_remove_cards (PASBook *book,
- const GNOME_Evolution_Addressbook_CardIdList *ids)
-{
- PASRequest *req;
- int i;
-
- req = g_new0 (PASRequest, 1);
- 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);
-}
-
-static void
-pas_book_queue_modify_card (PASBook *book, const char *vcard)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = ModifyCard;
- req->modify.vcard = g_strdup (vcard);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_cursor (PASBook *book, const char *search)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetCursor;
- req->get_cursor.search = g_strdup(search);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_vcard (PASBook *book, const char *id)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetVCard;
- req->get_vcard.id = g_strdup(id);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_authenticate_user (PASBook *book,
- const char *user, const char *passwd, const char *auth_method)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = AuthenticateUser;
- req->auth_user.user = g_strdup(user);
- req->auth_user.passwd = g_strdup(passwd);
- req->auth_user.auth_method = g_strdup(auth_method);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_supported_fields (PASBook *book)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetSupportedFields;
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_supported_auth_methods (PASBook *book)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetSupportedAuthMethods;
-
- pas_book_queue_request (book, req);
-}
-
-
static void
-pas_book_queue_get_book_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
+impl_GNOME_Evolution_Addressbook_Book_open (PortableServer_Servant servant,
+ const CORBA_boolean only_if_exists,
+ CORBA_Environment *ev)
{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetBookView;
- req->get_book_view.search = g_strdup(search);
-
- CORBA_exception_init (&ev);
-
- req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_book_view: Exception "
- "duplicating BookViewListener!\n");
- }
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- CORBA_exception_free (&ev);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_open\n");
- pas_book_queue_request (book, req);
+ pas_backend_open (pas_book_get_backend (book), book, only_if_exists);
}
static void
-pas_book_queue_get_completion_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
+impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant,
+ CORBA_Environment *ev)
{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetCompletionView;
- req->get_book_view.search = g_strdup(search);
-
- CORBA_exception_init (&ev);
-
- req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_completion_view: Exception "
- "duplicating BookViewListener!\n");
- }
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- CORBA_exception_free (&ev);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_open\n");
- pas_book_queue_request (book, req);
+ pas_backend_remove (pas_book_get_backend (book), book);
}
static void
-pas_book_queue_get_changes (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *change_id)
-{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetChanges;
- req->get_changes.change_id= g_strdup(change_id);
-
- CORBA_exception_init (&ev);
-
- req->get_changes.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_changes: Exception "
- "duplicating BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_check_connection (PASBook *book)
+impl_GNOME_Evolution_Addressbook_Book_getContact (PortableServer_Servant servant,
+ const CORBA_char *id,
+ CORBA_Environment *ev)
{
- PASRequest *req;
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- req = g_new0 (PASRequest, 1);
- req->op = CheckConnection;
+ printf ("impl_GNOME_Evolution_Addressbook_Book_getContact\n");
- pas_book_queue_request (book, req);
+ pas_backend_get_contact (pas_book_get_backend (book), book, id);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_getVCard (PortableServer_Servant servant,
- const CORBA_char *id,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_getContactList (PortableServer_Servant servant,
+ const CORBA_char *query,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_vcard (book, id);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_getContactList\n");
+
+ pas_backend_get_contact_list (pas_book_get_backend (book), book, query);
}
static void
@@ -273,90 +80,97 @@ impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant s
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_authenticate_user (book, user, passwd, auth_method);
+ pas_backend_authenticate_user (pas_book_get_backend (book), book,
+ user, passwd, auth_method);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_addContact (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_create_card (book, (const char *) vcard);
+ pas_backend_create_contact (pas_book_get_backend (book), book, vcard);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_removeCards (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardIdList *ids,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_removeContacts (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_ContactIdList *ids,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
+ int i;
+ GList *id_list = NULL;
+
+ for (i = 0; i < ids->_length; i ++)
+ id_list = g_list_append (id_list, ids->_buffer[i]);
- pas_book_queue_remove_cards (book, ids);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_modifyCard (PortableServer_Servant servant,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
+ pas_backend_remove_contacts (pas_book_get_backend (book), book, id_list);
- pas_book_queue_modify_card (book, (const char *) vcard);
+ g_list_free (id_list);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_getCursor (PortableServer_Servant servant,
- const CORBA_char *search,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_cursor (book, search);
+ pas_backend_modify_contact (pas_book_get_backend (book), book, vcard);
}
static void
impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
const GNOME_Evolution_Addressbook_BookViewListener listener,
const CORBA_char *search,
+ const GNOME_Evolution_Addressbook_stringlist* requested_fields,
+ const CORBA_long max_results,
CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
+ PASBackend *backend = pas_book_get_backend (book);
+ PASBackendCardSExp *card_sexp;
+ PASBookView *view;
- pas_book_queue_get_book_view (book, listener, search);
-}
+ g_warning ("impl_GNOME_Evolution_Addressbook_Book_getBookView (%s)\n", search);
+ /* we handle this entirely here, since it doesn't require any
+ backend involvement now that we have pas_book_view_start to
+ actually kick off the search. */
-static void
-impl_GNOME_Evolution_Addressbook_Book_getCompletionView (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
- const CORBA_char *search,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
+ card_sexp = pas_backend_card_sexp_new (search);
+ if (!card_sexp) {
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_InvalidQuery, NULL);
+ return;
+ }
+
+ view = pas_book_view_new (backend, listener, search, card_sexp);
- pas_book_queue_get_completion_view (book, listener, search);
+ if (!view) {
+ g_object_unref (card_sexp);
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_OtherError, NULL);
+ return;
+ }
+
+
+ pas_backend_add_book_view (backend, view);
+
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_Success, view);
+
+ g_object_unref (view);
}
+
static void
impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
const CORBA_char *change_id,
CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_changes (book, listener, change_id);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_checkConnection (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
-
- pas_book_queue_check_connection (book);
+ pas_backend_get_changes (pas_book_get_backend (book), book, change_id);
}
static char *
@@ -379,7 +193,7 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_supported_fields (book);
+ pas_backend_get_supported_fields (pas_book_get_backend (book), book);
}
static void
@@ -388,7 +202,16 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Se
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_supported_auth_methods (book);
+ pas_backend_get_supported_auth_methods (pas_book_get_backend (book), book);
+}
+
+static GNOME_Evolution_Addressbook_CallStatus
+impl_GNOME_Evolution_Addressbook_Book_cancelOperation (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
+
+ return pas_backend_cancel_operation (pas_book_get_backend (book), book);
}
/**
@@ -397,87 +220,59 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Se
PASBackend *
pas_book_get_backend (PASBook *book)
{
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), NULL);
return book->priv->backend;
}
-/**
- * pas_book_get_listener:
- */
GNOME_Evolution_Addressbook_BookListener
pas_book_get_listener (PASBook *book)
{
- g_return_val_if_fail (book != NULL, CORBA_OBJECT_NIL);
- g_return_val_if_fail (PAS_IS_BOOK (book), CORBA_OBJECT_NIL);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), CORBA_OBJECT_NIL);
return book->priv->listener;
}
-/**
- * pas_book_check_pending
- */
-gint
-pas_book_check_pending (PASBook *book)
+const char*
+pas_book_get_uri (PASBook *book)
{
- g_return_val_if_fail (book != NULL, -1);
- g_return_val_if_fail (PAS_IS_BOOK (book), -1);
-
- return g_list_length (book->priv->request_queue);
+ return book->priv->uri;
}
/**
- * pas_book_pop_request:
+ * pas_book_respond_open:
*/
-PASRequest *
-pas_book_pop_request (PASBook *book)
+void
+pas_book_respond_open (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status)
{
- GList *popped;
- PASRequest *req;
-
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
-
- if (book->priv->request_queue == NULL)
- return NULL;
-
- req = book->priv->request_queue->data;
+ CORBA_Environment ev;
- popped = book->priv->request_queue;
- book->priv->request_queue =
- g_list_remove_link (book->priv->request_queue, popped);
+ CORBA_exception_init (&ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (book->priv->listener, status, &ev);
- g_list_free_1 (popped);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_open: Exception "
+ "responding to BookListener!\n");
+ }
- return req;
+ CORBA_exception_free (&ev);
}
/**
- * pas_book_respond_open:
+ * pas_book_respond_remove:
*/
void
-pas_book_respond_open (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_remove (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
CORBA_exception_init (&ev);
-
- if (status == GNOME_Evolution_Addressbook_BookListener_Success) {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- book->priv->listener, status,
- bonobo_object_corba_objref (BONOBO_OBJECT (book)),
- &ev);
- } else {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- book->priv->listener, status,
- CORBA_OBJECT_NIL, &ev);
- }
-
+ GNOME_Evolution_Addressbook_BookListener_notifyBookRemoved (book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_open: Exception "
+ g_warning ("pas_book_respond_remove: Exception "
"responding to BookListener!\n");
}
@@ -488,16 +283,22 @@ pas_book_respond_open (PASBook *book,
* pas_book_respond_create:
*/
void
-pas_book_respond_create (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const char *id)
+pas_book_respond_create (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact)
{
CORBA_Environment ev;
+ if (status == GNOME_Evolution_Addressbook_Success) {
+ pas_backend_notify_update (book->priv->backend, contact);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardCreated (
- book->priv->listener, status, (char *)id, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactCreated (
+ book->priv->listener, status,
+ e_contact_get (contact, E_CONTACT_UID), &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_respond_create: Exception "
@@ -508,17 +309,25 @@ pas_book_respond_create (PASBook *book,
}
/**
- * pas_book_respond_remove:
+ * pas_book_respond_remove_contacts:
*/
void
-pas_book_respond_remove (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_remove_contacts (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *ids)
{
CORBA_Environment ev;
+ GList *i;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardsRemoved (
+ if (ids) {
+ for (i = ids; i; i = i->next)
+ pas_backend_notify_remove (book->priv->backend, i->data);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
+ GNOME_Evolution_Addressbook_BookListener_notifyContactsRemoved (
book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -533,14 +342,20 @@ pas_book_respond_remove (PASBook *book,
* pas_book_respond_modify:
*/
void
-pas_book_respond_modify (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_modify (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact)
{
CORBA_Environment ev;
+ if (status == GNOME_Evolution_Addressbook_Success) {
+ pas_backend_notify_update (book->priv->backend, contact);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardModified (
+ GNOME_Evolution_Addressbook_BookListener_notifyContactModified (
book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -556,7 +371,7 @@ pas_book_respond_modify (PASBook *book,
*/
void
pas_book_respond_authenticate_user (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
@@ -575,30 +390,28 @@ pas_book_respond_authenticate_user (PASBook *book,
void
pas_book_respond_get_supported_fields (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields)
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields)
{
CORBA_Environment ev;
GNOME_Evolution_Addressbook_stringlist stringlist;
int num_fields;
- EIterator *iter;
int i;
+ GList *iter;
CORBA_exception_init (&ev);
- num_fields = e_list_length (fields);
+ num_fields = g_list_length (fields);
stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
stringlist._maximum = num_fields;
stringlist._length = num_fields;
- iter = e_list_get_iterator (fields);
-
- for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) {
- stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter));
+ for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
+ stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data);
}
- g_object_unref (fields);
+ printf ("calling GNOME_Evolution_Addressbook_BookListener_notifySupportedFields\n");
GNOME_Evolution_Addressbook_BookListener_notifySupportedFields (
book->priv->listener, status,
@@ -612,31 +425,27 @@ pas_book_respond_get_supported_fields (PASBook *book,
void
pas_book_respond_get_supported_auth_methods (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *auth_methods)
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *auth_methods)
{
CORBA_Environment ev;
GNOME_Evolution_Addressbook_stringlist stringlist;
int num_auth_methods;
- EIterator *iter;
+ GList *iter;
int i;
CORBA_exception_init (&ev);
- num_auth_methods = e_list_length (auth_methods);
+ num_auth_methods = g_list_length (auth_methods);
stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods);
stringlist._maximum = num_auth_methods;
stringlist._length = num_auth_methods;
- iter = e_list_get_iterator (auth_methods);
-
- for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) {
- stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter));
+ for (i = 0, iter = auth_methods; iter; iter = iter->next, i ++) {
+ stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data);
}
- g_object_unref (auth_methods);
-
GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods (
book->priv->listener, status,
&stringlist,
@@ -647,30 +456,28 @@ pas_book_respond_get_supported_auth_methods (PASBook *book,
CORBA_free(stringlist._buffer);
}
-/**
- * pas_book_respond_get_cursor:
- */
-void
-pas_book_respond_get_cursor (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASCardCursor *cursor)
-{
- CORBA_Environment ev;
- CORBA_Object object;
-
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(cursor));
-
- GNOME_Evolution_Addressbook_BookListener_notifyCursorRequested (
- book->priv->listener, status, object, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_cursor: Exception "
- "responding to BookListener!\n");
+static void
+view_destroy(gpointer data, GObject *where_object_was)
+{
+ PASBook *book = (PASBook *)data;
+ EIterator *iterator;
+ gboolean success = FALSE;
+ EList *views = pas_backend_get_book_views (book->priv->backend);
+
+ for (iterator = e_list_get_iterator(views);
+ e_iterator_is_valid(iterator);
+ e_iterator_next(iterator)) {
+ const PASBookView *view = e_iterator_get(iterator);
+ if (view == (PASBookView*)where_object_was) {
+ e_iterator_delete(iterator);
+ success = TRUE;
+ break;
+ }
}
-
- CORBA_exception_free (&ev);
+ if (!success)
+ g_warning ("Failed to remove from book_views list");
+ g_object_unref(iterator);
+ g_object_unref(views);
}
/**
@@ -678,15 +485,21 @@ pas_book_respond_get_cursor (PASBook *book,
*/
void
pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ GNOME_Evolution_Addressbook_CallStatus status,
PASBookView *book_view)
{
CORBA_Environment ev;
- CORBA_Object object;
+ CORBA_Object object = CORBA_OBJECT_NIL;
+
+ printf ("pas_book_respond_get_book_view\n");
CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
+
+ if (book_view) {
+ object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
+
+ g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
+ }
GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
book->priv->listener, status, object, &ev);
@@ -700,100 +513,122 @@ pas_book_respond_get_book_view (PASBook *book,
}
/**
- * pas_book_respond_get_book_view:
+ * pas_book_respond_get_contact:
*/
void
-pas_book_respond_get_completion_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *completion_view)
+pas_book_respond_get_contact (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ char *vcard)
{
CORBA_Environment ev;
- CORBA_Object object;
CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(completion_view));
- GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
- book->priv->listener, status, object, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactRequested (book->priv->listener,
+ status,
+ vcard,
+ &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_completion_view: Exception "
- "responding to BookListener!\n");
- }
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-contact response");
CORBA_exception_free (&ev);
}
/**
- * pas_book_respond_get_changes:
+ * pas_book_respond_get_contact_list:
*/
void
-pas_book_respond_get_vcard (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- char *vcard)
+pas_book_respond_get_contact_list (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *card_list)
{
CORBA_Environment ev;
+ GNOME_Evolution_Addressbook_stringlist stringlist;
+ int num_cards;
+ int i;
+ GList *l;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardRequested (
- book->priv->listener, status, vcard, &ev);
+ num_cards = g_list_length (card_list);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_card: Exception "
- "responding to BookListener!\n");
- }
+ stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_cards);
+ stringlist._maximum = num_cards;
+ stringlist._length = num_cards;
- CORBA_exception_free (&ev);
-}
+ for (i = 0, l = card_list; l; l = l->next, i ++)
+ stringlist._buffer[i] = CORBA_string_dup (l->data);
-/**
- * pas_book_respond_get_changes:
- */
-void
-pas_book_respond_get_changes (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *book_view)
-{
- CORBA_Environment ev;
- CORBA_Object object;
+ g_list_foreach (card_list, (GFunc)g_free, NULL);
+ g_list_free (card_list);
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
- GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (
- book->priv->listener, status, object, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactListRequested (book->priv->listener,
+ status,
+ &stringlist,
+ &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_changes: Exception "
- "responding to BookListener!\n");
- }
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-contact-list response");
CORBA_exception_free (&ev);
+
+ CORBA_free(stringlist._buffer);
}
/**
- * pas_book_report_connection:
+ * pas_book_respond_get_changes:
*/
void
-pas_book_report_connection (PASBook *book,
- gboolean connected)
+pas_book_respond_get_changes (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *changes)
{
CORBA_Environment ev;
+ GNOME_Evolution_Addressbook_BookChangeList changelist;
+ int num_changes;
+ int i;
+ GList *l;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyConnectionStatus (
- book->priv->listener, (CORBA_boolean) connected, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_report_connection: Exception "
- "responding to BookListener!\n");
+ num_changes = g_list_length (changes);
+
+ changelist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_BookChangeItem_allocbuf (num_changes);
+ changelist._maximum = num_changes;
+ changelist._length = num_changes;
+
+ for (i = 0, l = changes; l; l = l->next, i ++) {
+ GNOME_Evolution_Addressbook_BookChangeItem *change = (GNOME_Evolution_Addressbook_BookChangeItem*)l->data;
+ changelist._buffer[i] = *change;
+ switch (change->_d) {
+ case GNOME_Evolution_Addressbook_ContactAdded:
+ changelist._buffer[i]._u.add_vcard = CORBA_string_dup (change->_u.add_vcard);
+ break;
+ case GNOME_Evolution_Addressbook_ContactModified:
+ changelist._buffer[i]._u.mod_vcard = CORBA_string_dup (change->_u.mod_vcard);
+ break;
+ case GNOME_Evolution_Addressbook_ContactDeleted:
+ changelist._buffer[i]._u.del_id = CORBA_string_dup (change->_u.del_id);
+ break;
+ }
}
+ g_list_foreach (changes, (GFunc)CORBA_free, NULL);
+ g_list_free (changes);
+
+ GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (book->priv->listener,
+ status,
+ &changelist,
+ &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-changes response");
+
CORBA_exception_free (&ev);
+
+ CORBA_free(changelist._buffer);
}
/**
@@ -821,7 +656,8 @@ pas_book_report_writable (PASBook *book,
static void
pas_book_construct (PASBook *book,
PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+ const char *uri,
+ GNOME_Evolution_Addressbook_BookListener listener)
{
PASBookPrivate *priv;
CORBA_Environment ev;
@@ -830,8 +666,6 @@ pas_book_construct (PASBook *book,
priv = book->priv;
- priv->backend = backend;
-
CORBA_exception_init (&ev);
book->priv->listener = CORBA_Object_duplicate (listener, &ev);
@@ -843,94 +677,31 @@ pas_book_construct (PASBook *book,
CORBA_exception_free (&ev);
- priv->listener = listener;
+ priv->backend = backend;
+ priv->uri = g_strdup (uri);
+
}
/**
* pas_book_new:
*/
PASBook *
-pas_book_new (PASBackend *backend,
+pas_book_new (PASBackend *backend,
+ const char *uri,
GNOME_Evolution_Addressbook_BookListener listener)
{
PASBook *book;
+ char *caps = pas_backend_get_static_capabilities (backend);
- book = g_object_new (PAS_TYPE_BOOK, NULL);
-
- pas_book_construct (book, backend, listener);
+ book = g_object_new (PAS_TYPE_BOOK,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
- return book;
-}
+ pas_book_construct (book, backend, uri, listener);
-void
-pas_book_free_request (PASRequest *req)
-{
- CORBA_Environment ev;
- switch (req->op) {
- case CreateCard:
- g_free (req->create.id);
- g_free (req->create.vcard);
- break;
- 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);
- break;
- case GetVCard:
- g_free (req->get_vcard.id);
- break;
- case GetCursor:
- g_free (req->get_cursor.search);
- break;
- case GetBookView:
- g_free (req->get_book_view.search);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_book_view.listener, &ev);
+ g_free (caps);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetBookView): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case GetCompletionView:
- g_free (req->get_completion_view.search);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_completion_view.listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetCompletionView): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case GetChanges:
- g_free (req->get_changes.change_id);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_changes.listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetChanges): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case CheckConnection:
- /* nothing to free */
- break;
- case AuthenticateUser:
- g_free (req->auth_user.user);
- g_free (req->auth_user.passwd);
- g_free (req->auth_user.auth_method);
- break;
- case GetSupportedFields:
- /* nothing to free */
- break;
- case GetSupportedAuthMethods:
- /* nothing to free */
- break;
- }
-
- g_free (req);
+ return book;
}
static void
@@ -939,24 +710,8 @@ pas_book_dispose (GObject *object)
PASBook *book = PAS_BOOK (object);
if (book->priv) {
- GList *l;
CORBA_Environment ev;
- for (l = book->priv->request_queue; l != NULL; l = l->next) {
- pas_book_free_request ((PASRequest *)l->data);
- }
- g_list_free (book->priv->request_queue);
-
- /* We should never ever have timeout_id == 0 when we
- get destroyed, unless there is some sort of
- reference counting bug. Still, we do this to try
- to avoid horrible crashes in those situations. */
- if (book->priv->timeout_id) {
- g_warning ("PASBook destroyed with non-zero timeout_id. This shouldn't happen.");
- g_source_remove (book->priv->timeout_id);
- book->priv->timeout_id = 0;
- }
-
CORBA_exception_init (&ev);
CORBA_Object_release (book->priv->listener, &ev);
@@ -965,6 +720,7 @@ pas_book_dispose (GObject *object)
CORBA_exception_free (&ev);
+ g_free (book->priv->uri);
g_free (book->priv);
book->priv = NULL;
}
@@ -981,42 +737,30 @@ pas_book_class_init (PASBookClass *klass)
pas_book_parent_class = g_type_class_peek_parent (klass);
- pas_book_signals [REQUESTS_QUEUED] =
- g_signal_new ("requests_queued",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PASBookClass, requests_queued),
- NULL, NULL,
- pas_marshal_NONE__NONE,
- G_TYPE_NONE, 0);
-
object_class->dispose = pas_book_dispose;
epv = &klass->epv;
- epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard;
+ epv->open = impl_GNOME_Evolution_Addressbook_Book_open;
+ epv->remove = impl_GNOME_Evolution_Addressbook_Book_remove;
+ epv->getContact = impl_GNOME_Evolution_Addressbook_Book_getContact;
+ epv->getContactList = impl_GNOME_Evolution_Addressbook_Book_getContactList;
epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
- epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard;
- 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->addContact = impl_GNOME_Evolution_Addressbook_Book_addContact;
+ epv->removeContacts = impl_GNOME_Evolution_Addressbook_Book_removeContacts;
+ epv->modifyContact = impl_GNOME_Evolution_Addressbook_Book_modifyContact;
epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields;
epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods;
- epv->getCursor = impl_GNOME_Evolution_Addressbook_Book_getCursor;
epv->getBookView = impl_GNOME_Evolution_Addressbook_Book_getBookView;
- epv->getCompletionView = impl_GNOME_Evolution_Addressbook_Book_getCompletionView;
epv->getChanges = impl_GNOME_Evolution_Addressbook_Book_getChanges;
+ epv->cancelOperation = impl_GNOME_Evolution_Addressbook_Book_cancelOperation;
}
static void
pas_book_init (PASBook *book)
{
book->priv = g_new0 (PASBookPrivate, 1);
- book->priv->timeout_id = 0;
- book->priv->request_queue = NULL;
- book->priv->timeout_id = 0;
- book->priv->timeout_lock = FALSE;
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h
index 761f906437..2cb84569c2 100644
--- a/addressbook/backend/pas/pas-book.h
+++ b/addressbook/backend/pas/pas-book.h
@@ -12,13 +12,11 @@
#ifndef __PAS_BOOK_H__
#define __PAS_BOOK_H__
-#include <bonobo/bonobo-object.h>
#include <pas/addressbook.h>
-#include <pas/pas-book-view.h>
+#include <bonobo/bonobo-object.h>
#include "e-util/e-list.h"
-#include <pas/pas-backend.h>
-#include <pas/pas-card-cursor.h>
+#include <pas/pas-types.h>
#define PAS_TYPE_BOOK (pas_book_get_type ())
#define PAS_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK, PASBook))
@@ -27,164 +25,68 @@
#define PAS_IS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK))
#define PAS_BOOK_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK, PASBookClass))
-typedef struct _PASBook PASBook;
typedef struct _PASBookPrivate PASBookPrivate;
-typedef enum {
- CreateCard,
- RemoveCards,
- ModifyCard,
- GetVCard,
- GetCursor,
- GetBookView,
- GetCompletionView,
- GetChanges,
- CheckConnection,
- AuthenticateUser,
- GetSupportedFields,
- GetSupportedAuthMethods
-} PASOperation;
-
-typedef struct {
- PASOperation op;
- char *id;
- char *vcard;
-} PASCreateCardRequest;
-
-typedef struct {
- PASOperation op;
- GList *ids;
-} PASRemoveCardsRequest;
-
-typedef struct {
- PASOperation op;
- char *vcard;
-} PASModifyCardRequest;
-
-typedef struct {
- PASOperation op;
- char *id;
-} PASGetVCardRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
-} PASGetCursorRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetBookViewRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetCompletionViewRequest;
-
-typedef struct {
- PASOperation op;
- char *change_id;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetChangesRequest;
-
-typedef struct {
- PASOperation op;
-} PASCheckConnectionRequest;
-
-typedef struct {
- PASOperation op;
- char *user;
- char *passwd;
- char *auth_method;
-} PASAuthenticateUserRequest;
-
-typedef struct {
- PASOperation op;
-} PASGetSupportedFieldsRequest;
-
-typedef struct {
- PASOperation op;
-} PASGetSupportedAuthMethodsRequest;
-
-typedef union {
- PASOperation op;
-
- PASCreateCardRequest create;
- PASRemoveCardsRequest remove;
- PASModifyCardRequest modify;
- PASGetVCardRequest get_vcard;
- PASGetCursorRequest get_cursor;
- PASGetBookViewRequest get_book_view;
- PASGetCompletionViewRequest get_completion_view;
- PASGetChangesRequest get_changes;
- PASCheckConnectionRequest check_connection;
- PASAuthenticateUserRequest auth_user;
- PASGetSupportedFieldsRequest get_supported_fields;
- PASGetSupportedAuthMethodsRequest get_supported_auth_methods;
-} PASRequest;
-
struct _PASBook {
- BonoboObject parent_object;
- PASBookPrivate *priv;
+ BonoboObject parent_object;
+ PASBookPrivate *priv;
};
-typedef struct {
+struct _PASBookClass {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Addressbook_Book__epv epv;
- /* Signals */
- void (*requests_queued) (void);
-} PASBookClass;
-
-
-typedef gboolean (*PASBookCanWriteFn) (PASBook *book);
-typedef gboolean (*PASBookCanWriteCardFn) (PASBook *book, const char *id);
-
-PASBook *pas_book_new (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener);
-PASBackend *pas_book_get_backend (PASBook *book);
-GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book);
-int pas_book_check_pending (PASBook *book);
-PASRequest *pas_book_pop_request (PASBook *book);
-void pas_book_free_request (PASRequest *request);
-void pas_book_respond_open (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_create (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const char *id);
-void pas_book_respond_remove (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_modify (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_authenticate_user (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_get_supported_fields (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields);
-void pas_book_respond_get_supported_auth_methods (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields);
-
-void pas_book_respond_get_cursor (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASCardCursor *cursor);
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+};
+
+
+PASBook *pas_book_new (PASBackend *backend,
+ const char *uri,
+ GNOME_Evolution_Addressbook_BookListener listener);
+GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book);
+PASBackend *pas_book_get_backend (PASBook *book);
+const char *pas_book_get_uri (PASBook *book);
+
+void pas_book_respond_open (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_remove (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_create (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact);
+void pas_book_respond_remove_contacts (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *ids);
+void pas_book_respond_modify (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact);
+void pas_book_respond_authenticate_user (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_get_supported_fields (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields);
+void pas_book_respond_get_supported_auth_methods (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields);
+
void pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ GNOME_Evolution_Addressbook_CallStatus status,
PASBookView *book_view);
-void pas_book_respond_get_completion_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *completion_view);
-void pas_book_respond_get_vcard (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+void pas_book_respond_get_contact (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
char *vcard);
-void pas_book_respond_get_changes (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *book_view);
-void pas_book_report_connection (PASBook *book,
- gboolean connected);
+void pas_book_respond_get_contact_list (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *cards);
+void pas_book_respond_get_changes (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *changes);
void pas_book_report_writable (PASBook *book,
gboolean writable);
diff --git a/addressbook/backend/pas/pas-card-cursor.c b/addressbook/backend/pas/pas-card-cursor.c
deleted file mode 100644
index 9637bb1fb7..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-card-cursor.c: Implements card cursors.
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com.
- */
-
-#include <config.h>
-#include <bonobo/bonobo-main.h>
-#include "addressbook.h"
-#include "pas-card-cursor.h"
-
-struct _PASCardCursorPrivate {
- long (*get_length) (PASCardCursor *cursor, gpointer data);
- char * (*get_nth) (PASCardCursor *cursor, long n, gpointer data);
- gpointer data;
-};
-
-/*
- * A pointer to our parent object class
- */
-static BonoboObjectClass *parent_class;
-
-/*
- * Implemented GObject::dispose
- */
-static void
-pas_card_cursor_dispose (GObject *object)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (object);
-
- if ( cursor->priv ) {
- g_free ( cursor->priv );
- cursor->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/*
- * CORBA Demo::Echo::echo method implementation
- */
-static CORBA_long
-impl_pas_card_cursor_get_length (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant));
- if ( cursor->priv->get_length )
- return cursor->priv->get_length( cursor, cursor->priv->data );
- else
- return 0;
-}
-
-/*
- * CORBA Demo::Echo::echo method implementation
- */
-static char *
-impl_pas_card_cursor_get_nth (PortableServer_Servant servant,
- const CORBA_long n,
- CORBA_Environment *ev)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant));
- if ( cursor->priv->get_nth ) {
- char *vcard = cursor->priv->get_nth( cursor, n, cursor->priv->data );
- char *retval = CORBA_string_dup (vcard);
- g_free (vcard);
- return retval;
- } else
- return CORBA_string_dup ("");
-}
-
-static void
-pas_card_cursor_class_init (PASCardCursorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- POA_GNOME_Evolution_Addressbook_CardCursor__epv *epv;
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = pas_card_cursor_dispose;
-
-
- epv = &klass->epv;
-
- epv->count = impl_pas_card_cursor_get_length;
- epv->getNth = impl_pas_card_cursor_get_nth;
-}
-
-static void
-pas_card_cursor_init (PASCardCursor *cursor)
-{
- cursor->priv = g_new0(PASCardCursorPrivate, 1);
- cursor->priv->get_length = NULL;
- cursor->priv->get_nth = NULL;
- cursor->priv->data = NULL;
-}
-
-static void
-pas_card_cursor_construct (PASCardCursor *cursor,
- PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- PASCardCursorPrivate *priv;
-
- 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;
-}
-
-PASCardCursor *
-pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- PASCardCursor *cursor;
-
- cursor = g_object_new (PAS_TYPE_CARD_CURSOR, NULL);
-
- pas_card_cursor_construct (cursor,
- get_length,
- get_nth,
- data);
-
- return cursor;
-}
-
-BONOBO_TYPE_FUNC_FULL (
- PASCardCursor,
- GNOME_Evolution_Addressbook_CardCursor,
- BONOBO_TYPE_OBJECT,
- pas_card_cursor);
diff --git a/addressbook/backend/pas/pas-card-cursor.h b/addressbook/backend/pas/pas-card-cursor.h
deleted file mode 100644
index db5b05c0c2..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_CARD_CURSOR_H__
-#define __PAS_CARD_CURSOR_H__
-
-#include <bonobo/bonobo-object.h>
-#include <pas/addressbook.h>
-
-G_BEGIN_DECLS
-
-#define PAS_TYPE_CARD_CURSOR (pas_card_cursor_get_type ())
-#define PAS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_CARD_CURSOR, PASCardCursor))
-#define PAS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_CARD_CURSOR, PASCardCursorClass))
-#define PAS_IS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_CARD_CURSOR))
-#define PAS_IS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_CARD_CURSOR))
-#define PAS_CARD_CURSOR_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_CARD_CURSOR, PASCardCursorClass))
-
-typedef struct _PASCardCursor PASCardCursor;
-typedef struct _PASCardCursorPrivate PASCardCursorPrivate;
-typedef struct _PASCardCursorClass PASCardCursorClass;
-
-typedef long (*PASCardCursorLengthFunc) (PASCardCursor *cursor, gpointer data);
-typedef char * (*PASCardCursorNthFunc) (PASCardCursor *cursor, long n, gpointer data);
-
-struct _PASCardCursor {
- BonoboObject parent;
- PASCardCursorPrivate *priv;
-};
-
-struct _PASCardCursorClass {
- BonoboObjectClass parent;
-
- POA_GNOME_Evolution_Addressbook_CardCursor__epv epv;
-};
-
-
-
-/* Creating a new addressbook. */
-PASCardCursor *pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data);
-
-GType pas_card_cursor_get_type (void);
-POA_GNOME_Evolution_Addressbook_CardCursor__epv *
- pas_card_cursor_get_epv (void);
-
-G_END_DECLS
-
-#endif /* ! __PAS_CARD_CURSOR_H__ */
diff --git a/addressbook/backend/pas/pas-marshal.list b/addressbook/backend/pas/pas-marshal.list
index fa33740eaa..9d6744db44 100644
--- a/addressbook/backend/pas/pas-marshal.list
+++ b/addressbook/backend/pas/pas-marshal.list
@@ -1 +1,2 @@
NONE:NONE
+NONE:POINTER
diff --git a/addressbook/backend/pas/pas-types.h b/addressbook/backend/pas/pas-types.h
new file mode 100644
index 0000000000..19611a4e23
--- /dev/null
+++ b/addressbook/backend/pas/pas-types.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Blanket header containing the typedefs for object types used in the
+ * PAS stuff, so we can disentangle the #includes.
+ *
+ * Author: Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ */
+
+#ifndef __PAS_TYPES_H__
+#define __PAS_TYPES_H__
+
+typedef struct _PASBookView PASBookView;
+typedef struct _PASBookViewClass PASBookViewClass;
+
+typedef struct _PASBackendCardSExp PASBackendCardSExp;
+typedef struct _PASBackendCardSExpClass PASBackendCardSExpClass;
+
+typedef struct _PASBackend PASBackend;
+typedef struct _PASBackendClass PASBackendClass;
+
+typedef struct _PASBackendSummary PASBackendSummary;
+typedef struct _PASBackendSummaryClass PASBackendSummaryClass;
+
+typedef struct _PASBackendSync PASBackendSync;
+typedef struct _PASBackendSyncClass PASBackendSyncClass;
+
+typedef struct _PASBook PASBook;
+typedef struct _PASBookClass PASBookClass;
+
+#endif /* __PAS_TYPES_H__ */
diff --git a/addressbook/backend/pas/ximian-vcard.h b/addressbook/backend/pas/ximian-vcard.h
new file mode 100644
index 0000000000..961a5cadb4
--- /dev/null
+++ b/addressbook/backend/pas/ximian-vcard.h
@@ -0,0 +1,81 @@
+#define XIMIAN_VCARD \
+"BEGIN:VCARD\n" \
+"X-EVOLUTION-FILE-AS:Ximian\\, Inc.\n" \
+"ADR;TYPE=WORK:;Suite 3 West;401 Park Drive;Boston;MA;02215;USA\n" \
+"LABEL;TYPE=WORK:401 Park Drive\\nSuite 3 West\\nBoston\\, MA\\n02215\\nUSA\n" \
+"TEL;WORK;VOICE:(617) 375-3800\n" \
+"TEL;WORK;FAX:(617) 236-8630\n" \
+"EMAIL;INTERNET:hello@ximian.com\n" \
+"URL:http://www.ximian.com/\n" \
+"ORG:Ximian\\, Inc.;\n" \
+"NOTE:Welcome to the Ximian Addressbook.\n" \
+"PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRo\n" \
+" IFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCM\n" \
+" cHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMj\n" \
+" IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAbgBkAwEiAAIRAQMRAf/EA\n" \
+" BwAAAIDAQEBAQAAAAAAAAAAAAAHBQYIBAMBAv/EAEYQAAEDAwEFBgMEBgQPAAAAAAECAwQABREG\n" \
+" BxIhMWETIkFRcYEUkaEIMkLBFSNSsbLRFmJydRgkMzY3Q0RGgpKTosLh8P/EABsBAQACAwEBAAA\n" \
+" AAAAAAAAAAAAEBQIDBgEH/8QALREAAQMCAwYGAgMAAAAAAAAAAQACAwQREiFRBRMiMUFhMnGBkb\n" \
+" HRBsEUofD/2gAMAwEAAhEDEQA/AH/RRRREVwXe9W2wwFzbpNZixkc1uqwPQeZ6CoHXevLfom1ds\n" \
+" 9h6a6D8PGCsFZHMk+CR4n86yzdbrqfaZqYBSnp0hRPZMoG62ynoOSR1Pua8Lg0XPJegX5Jv6k+0\n" \
+" bBjrWxp22LlkcBIlHs0HqEjiR64peT9umupqyWrhHhpP4WI6eHureNW7Tmw+DGaTI1FJVJdxksM\n" \
+" qKG09CrmfbFMCHpCw2xATDs8JrH4gykq+Z4mqifbMUZsxpd/QUllK53M2SCb2xa+bXvf0gcV0Uw\n" \
+" 0R/DVktH2hdUwlpFxjQrg1490tLPuOH0pvv2qE4jdchx1p8lNAj91Va87OtM3RCt+2Nx3Dyci/q\n" \
+" yPYcD7g1EZ+RR4rSMI9b/S2mhdbhKsmkdtWmNTuNxnXVW2cvgGZRASo+SV8j74PSmOlQUMpORWP\n" \
+" NU7MrjY0rlQFmdDTxOE4cQOo8R1Hyqe2Z7ZJ2m32bXfHnJVpJCUuqO8uP7+Kenh4eVXkFRFUMxx\n" \
+" G4UOSN0Zs4LU1FeEOWxOityYzqHWXEhSFoOQoHkQa963rBFFFFERUdfr1E09Y5d1mr3Y8ZsrV5n\n" \
+" yA6k4A6mpGkL9ojUym0W/TrLmAsGU+AeYBwgfPJ/4RREqrrcb1tJ1oUpBXLmObqUZ7rSByT0SkZ\n" \
+" J8zk1pHQmiLXo+zpbabC3SAp55Q7zyvM9PIUudiGmURbS7fpCMvzFFton8LSTxx6qH0FM7VV9VY\n" \
+" 9MzZ7aQt5tASw3+26ohKB/zEVSVFVvZzGMw02tqe/kpbI8LMR6/C/Xxq9QagfbbP+IW1QQ4Rycf\n" \
+" xncHRAIJ/rEfsmu2a9Fgsl2XIZjtj8bqwgfM1+9L2VFksESAV9o6hG886ebjqjvLWepUSarutdn\n" \
+" MXV+obRcZks/CwCQ5DKMpeBOTxzwzgA9KwfTtfxPOSB5GQUXc9pOjoC+zXe2HV5xiOC6PmkEfWp\n" \
+" xe6tAWghSVDIIOQRXxekNOx4b0WPZYLLTram19mwlJKSMHjjNUzQd2dZM7SNxczcLOsttqVzdYz\n" \
+" 3FewI9iKpK2mjMZdFe7ed9NfT9qZDI4OAd1Vkko50ndoui22kuXq2NBOO9JZSOH9sD9/z86c8gc\n" \
+" DUJNQlaFJUkKSoYII4EVGoKp9PIHt9e6lyRNlZhcqlsJ2guQpydL3F4mO7kw1KP3Fcyj0PEjrnz\n" \
+" rSAIIyOVYfvsJ3TGqlCKpTfYuJfjLHMDOR8jw9q2Foy+o1FpWBckY/XMpUoeRxxHsciu/jeJGB7\n" \
+" eRXPvaWuLT0U/RRRWaxQeVY82x3BVw2oXbJyhgoZR0AQM/UmthK+6fSsWbRQW9pV73x/tZPtwNE\n" \
+" Wj9Nw0WuwwIKQAGI6G/cAZ+tRW0lx5nTEW4Ntqdat9xjy5CEjJLSFZP5H2qaYdCkpUk5BGQa7Ap\n" \
+" DrSm3EpWhYKVJUMgg8wRXz+kqyyTG7VXUsV22Clrfc48+CzMiPIejvIC23EHIUDXNe79b7HbXbh\n" \
+" c5SI8ZvmtZ5nyA5k9BS7d0nfdMPuSdD3JtEZaitdom5Uznx3DzT6cPWkvq/V1611fGW5nZtBCgy\n" \
+" zFbXhtCycE5JxknxPhXR07RUeB3D11H+9lAfwcxmrrqLbxcHpikWGAw1FScByUkqWvrgEBPpxqi\n" \
+" ztdXWdqmNqIIjx7gykJUphJCXAM/eBJ5g4PQCmBZNiDKWEu364uF0jJYh4AT6qUDn2FVu6bPIkT\n" \
+" aTB08xKeMOU2H99eCtKRvZGQMZ7hwceNZxVGzsbmMzIBv5dfNeOjnsCdUwbTtKsV8nJgIccZkqw\n" \
+" lJcThDqvJJz8s4zUtLVzpc2vZZKt+qBIkyUKt0V0ONKSe+7g5SCPDr9Kv0tznXP1cNMyQfxnXBC\n" \
+" tqUyuB3gslftPjJLkGWB3u82o/Ij86bf2e7iqRoxyIpWfhpC0JHQ4V/5GlVtJcBt0RPiXif+00w\n" \
+" Ps5BQtNxP4TJP8Ka6rZZJpW37/Kq68ATlPeiiirBQ0HlWR9t9qVbtpEp/dwiY0h5J8Mgbp/h+ta\n" \
+" 4pM7fdKLumn2rxGbKn4BKl4HEtn73ywD7GiL7o28JuulLbKCsqLKUL/tJ7p+oqyIe4c6RGyzU4g\n" \
+" THLNJc3WpCt9gk8A54j3GPcdaZuoosy82V23QpaYpkEIdeIJKUeIAHieXPkTXA11DuassJsCefY\n" \
+" /SvYZN5FiGZU9edRwLDAXJny2mRukoStQBWQOQHjSjg7PYE7ZmzcZb7cG6KK5CZD6txOCcJQvPg\n" \
+" QAQfAn2q6RNOWi1D9J3R5dwlR2xmZPVv9mlI8ByTj59ar09Lm0jUIQl5Y0zAUMrQSPiXfHHpyz4\n" \
+" D1qTRvMQIieQAQXOtllfIDre/X2WqVmI8Qz6D9q0bP9SO37SrSpW8ZUVXw7q+YcKeSgeRyMZ65q\n" \
+" qammvWTalEv1yjOJtaWfh25CBvBOUkHPlxUeHlyq/MiPCitxorSGWG07qG0DASK45xZlx3GJDaH\n" \
+" WljCkLGQR6VGinY2ofIG8Lri2gOi37hxYG3zC+uT2HY6ZDbyFMrAUlwK7pB5HNRcp7nxqpzdN3G\n" \
+" CFQ7NObTa3nApcaSN/suOe4SDw6VK3O4swojsp9WGmxk9fIDrW4UzWkbt2K/v691vjec8YtZUTa\n" \
+" BL+IuMaIjiWWytXQn/wBD608tgtrVC0W2+tOFSFqd9icD6AVnmFFl6n1AhoAmRPdwcfgR4n2H7q\n" \
+" 2Ppi1N2exRojaQlKEBIHkAK7Gmi3MTWaLn6iTeSF+qmaKKK3rSiuedEanQ3I7qQpC0kEEZzXRRR\n" \
+" FjnaRoSVoq/KcYQv9HOr3mHB/qzz3SenhVi0ftAbnNNwLo6G5iQEodUcJd9fJX760ZqLTkHUdsd\n" \
+" hTWEOtuJwQoVl/XGyS7aakOPwGnJcDORujK0DqPH2qJV0cdUzC/0Oi3QTuhddqY84IuFukwnFFK\n" \
+" JDSmlEcwFDGR86ISI1tgtQ4jYaYaTuoSP/udJS1azvFoAZLnbsp4dm/klPQHmKs0faVEWkfEw32\n" \
+" 1f1CFj8q56XZNSwYG5t7fSt46yB5ucimM5L4c643pXWqU5tCteMpRKUfIIH86ipmvnnAUwoQSf2\n" \
+" 3lZ+g/nWEey5yfCtrquBo8Su0+4sQ46pEp1LTSeZUfoPOlnfr67fZKQlK0QkK/VtficV5nrXOkX\n" \
+" XUk9KQHp0gnghI7qPyAp1bOdkCmH2rneQHHxxQjHdb9OvWr2j2c2Didm74VZVVplGFuQXRsc2fO\n" \
+" Qgb1cmsSXQN1JH+TT4D+dPEAAADkK848duMylppISkDGBXrVkoCKKKKIiiqrrbX9m0JARIua1re\n" \
+" dJDMdoArcI58+AA8zVLsO26RqiS9Gsukpct5lHaKbTLaSrd8wFEZ9s0RN6vGRGZktlDqAoHzFKq\n" \
+" JtomzrPOuzGjZvwEBRTJfckttpbUOae9jJ5cBk8R514Wrbo7e489+3aTlvtQGTIkqElsdm2Mkq4\n" \
+" 4zyPKiKf1Hsj09flKdXEQh4/jR3VfMUvJ/2et1ZMOe8keSgFfyqz2LbfJ1M9IZs2kJsx2O0XnEN\n" \
+" yEAhA4ZwcZ58hxr7ZdtkvUS5SbTo2fJMRsuPkPoSG0jzKsDPPhz4HyoipDewC47+FXFWOjYH51Y\n" \
+" bTsAgtrSqc88/jwWrA+QxUlYtujupZ6oNo0nLlSUtqdKEyW04SMZOVYHiKjP8ACUt5/wB3pX/XT\n" \
+" /KiJnWLQ1nsTSURorad39lIFWZKUoThIAHSlNqDbLP0siKu96MnQ0ygSyVyGzvYxnlnB4jga87F\n" \
+" ttlamXJbs2j50xcZvtXUtyEZCfPB5+gyaIm9RSetm3J68RbhJgaSmPM25vtZaviW09knjxIOM8j\n" \
+" y8q7LHtzstwv/AOhrlBftkkudkFOLS43v5xgqSeHHx5daImrRX5QtK0hSTkGiiLMP2ho8wa1iSn\n" \
+" QoxVRQ20fAKClFQ9eIqq7LLJe7vreG7ZZCoZhqD8iZjustjnnwORkY8c+Wa1ZqbStt1PBMa4MId\n" \
+" Rz7wzg+dL8bEbA1vpa7RtK+CkpdWAfXjRFB7UpCNe6Kdm6NnJft1qluKuUJlvdKznPbYH3hzPXJ\n" \
+" PMGqZsk/zc2gf3G5/Cumc3sRsTO92Rcb3uB3XVjP1r4jYfYGwoN76QsYUEurGR5HjREudhUt2BP\n" \
+" 1TMYID0eyuuoJGRvJII+oq96I2iwtVz7rb7ZZWbalyzyJ9wKUjLsrKEkjH4cE8+Jz049bew+wNb\n" \
+" 3Z76N4YO66sZHlzob2H2Bkktb6CRglLqxkeXOiJZbAv9IMj+7X/wB6ag9lGnEaj17CRJA+BhZmy\n" \
+" lK+6EI44PQq3R6E06W9h9gZVvNb6FYxlLqwcfOhvYhYWt7s99G8MK3XVjI68aIo7UxgbR9IajhQ\n" \
+" 7/Du9yiSF3S3tMNrStlkAAt94DPDI4eJFUvYfNetqNYz4xAfjWZx5skZAUnJHD1FMVrYhYWVbzW\n" \
+" +2ojGUOrBx86EbD7A0FBvfRvDCt11YyPI8aIo23zdP6i2e621TaUJiXCfa1IucFPJt5KVnfHRWS\n" \
+" euPPNZ2YadfkNsspUp1aglCU8yTyrTSNh9gbCgjfSFjCgl1YyPI8al9PbItP2WamUywkuJ5KOVE\n" \
+" emeVEVw02ZH9H4YkEqdDYCifE4oqXbaS02lCRhIGBRRF//Z\n" \
+"END:VCARD"
diff --git a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in b/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
index 6d46c5fbbe..6b3b252377 100644
--- a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
+++ b/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
@@ -1,6 +1,6 @@
<oaf_info>
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Factory"
+<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Factory_2"
type="shlib"
location="@COMPONENTDIR@/libevolution-addressbook.so">
@@ -13,9 +13,9 @@
</oaf_server>
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_MiniCard_Control"
+<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Control:1.0"/>
@@ -32,9 +32,9 @@
</oaf_server>
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Control"
+<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Control_2"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/addressbook-control:1.0"/>
@@ -46,27 +46,22 @@
</oaf_server>
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_ShellComponent"
+<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Component"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/>
+ <item value="IDL:GNOME/Evolution/Component:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string"
_value="Evolution Addressbook component"/>
- <oaf_attribute name="evolution:shell_component_icon" type="string"
- value="evolution-contacts.png"/>
- <oaf_attribute name="evolution:shell_component_launch_order" type="number"
- value="2"/>
-
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/address-widget:1.0"/>
@@ -80,7 +75,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressPopup"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/address-widget:1.0"/>
@@ -94,7 +89,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/ConfigControl:1.0"/>
diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am
index e13f8d853b..4234997e1d 100644
--- a/addressbook/gui/component/Makefile.am
+++ b/addressbook/gui/component/Makefile.am
@@ -9,7 +9,6 @@ INCLUDES = \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir)/addressbook/gui/contact-editor \
-I$(top_srcdir)/addressbook/gui/contact-list-editor \
- -I$(top_srcdir)/addressbook/gui/minicard \
-I$(top_srcdir)/addressbook/gui/widgets \
-I$(top_srcdir)/addressbook/backend \
-I$(top_builddir)/addressbook/backend \
@@ -38,26 +37,22 @@ libevolution_addressbook_la_SOURCES = \
addressbook-storage.h \
addressbook.c \
addressbook.h \
- component-factory.c \
- e-cardlist-model.c \
- e-cardlist-model.h \
- e-address-widget.h \
- e-address-widget.c \
- e-address-popup.h \
- e-address-popup.c
+ component-factory.c
+
+# $(top_builddir)/addressbook/printing/libecontactprint.la
libevolution_addressbook_la_LIBADD = \
- select-names/libeselectnames.la \
+ $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
$(top_builddir)/shell/libeshell.la \
- $(top_builddir)/addressbook/gui/widgets/libeminicard.la \
- $(top_builddir)/addressbook/printing/libecontactprint.la \
+ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \
+ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \
$(top_builddir)/addressbook/gui/search/libeaddressbooksearch.la \
$(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
$(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/addressbook/gui/merging/libecardmerging.la \
$(top_builddir)/widgets/menus/libmenus.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS)
diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c
index cdfeeb9755..c323a1bd78 100644
--- a/addressbook/gui/component/addressbook-component.c
+++ b/addressbook/gui/component/addressbook-component.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* addressbook-component.c
*
- * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -17,633 +17,170 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * Author: Ettore Perazzoli
+ * Author: Ettore Perazzoli <ettore@ximian.com>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libgnomevfs/gnome-vfs-types.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-directory.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-main.h>
-
-#include "evolution-shell-component.h"
-#include "evolution-shell-component-dnd.h"
-#include "evolution-storage.h"
-#include "e-folder-list.h"
-
-#include "ebook/e-book.h"
-#include "ebook/e-card.h"
-#include "ebook/e-book-util.h"
-
-#include "addressbook-config.h"
-#include "addressbook-storage.h"
-#include "addressbook-component.h"
-#include "addressbook.h"
-#include "addressbook/gui/merging/e-card-merging.h"
-#include "addressbook/gui/widgets/e-addressbook-util.h"
-
-
-
-#define GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_ShellComponent"
-
-EvolutionShellClient *global_shell_client = NULL;
+/* EPFIXME: Add autocompletion setting. */
-EvolutionShellClient *
-addressbook_component_get_shell_client (void)
-{
- return global_shell_client;
-}
-static char *accepted_dnd_types[] = {
- "text/x-vcard",
- NULL
-};
+#include <config.h>
-static const EvolutionShellComponentFolderType folder_types[] = {
- { "contacts", "evolution-contacts.png", N_("Contacts"), N_("Folder containing contact information"),
- TRUE, accepted_dnd_types, NULL },
- { "contacts/ldap", "ldap.png", N_("LDAP Server"), N_("LDAP server containing contact information"),
- FALSE, accepted_dnd_types, NULL },
- { "contacts/public", "evolution-contacts.png", N_("Public Contacts"), N_("Public folder containing contact information"),
- FALSE, accepted_dnd_types, NULL },
- { NULL }
-};
+#include "addressbook-component.h"
-#define IS_CONTACT_TYPE(x) (g_ascii_strcasecmp((x), "contacts") == 0 || g_ascii_strcasecmp ((x), "contacts/ldap") == 0 || g_ascii_strcasecmp((x), "contacts/public") == 0)
-
-/* EvolutionShellComponent methods and signals. */
-
-static EvolutionShellComponentResult
-create_view (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const char *view_info,
- BonoboControl **control_return,
- void *closure)
-{
- BonoboControl *control;
+#include "addressbook.h"
- if (!IS_CONTACT_TYPE (type))
- return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE;
+#include "widgets/misc/e-source-selector.h"
- control = addressbook_new_control ();
- bonobo_control_set_property (control, NULL, "folder_uri", TC_CORBA_string, physical_uri, NULL);
+#include <gtk/gtkscrolledwindow.h>
+#include <gconf/gconf-client.h>
- *control_return = control;
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
+#define PARENT_TYPE bonobo_object_get_type ()
+static BonoboObjectClass *parent_class = NULL;
-static void
-create_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- CORBA_Environment ev;
- GNOME_Evolution_ShellComponentListener_Result result;
+struct _AddressbookComponentPrivate {
+ GConfClient *gconf_client;
+ ESourceList *source_list;
+};
- if (!IS_CONTACT_TYPE (type))
- result = GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE;
- else
- result = GNOME_Evolution_ShellComponentListener_OK;
- CORBA_exception_init(&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult(listener, result, &ev);
- CORBA_exception_free(&ev);
-}
+/* Utility functions. */
static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+load_uri_for_selection (ESourceSelector *selector,
+ BonoboControl *view_control)
{
- CORBA_Environment ev;
- char *db_path, *summary_path, *subdir_path;
- struct stat sb;
- int rv;
-
- CORBA_exception_init(&ev);
-
- if (!IS_CONTACT_TYPE (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
-
- if (!strncmp (physical_uri, "ldap://", 7)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_OPERATION,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
- if (strncmp (physical_uri, "file://", 7)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
-
- subdir_path = g_build_filename (physical_uri + 7, "subfolders", NULL);
- rv = stat (subdir_path, &sb);
- g_free (subdir_path);
- if (rv != -1) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_HAS_SUBFOLDERS,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
-
- db_path = g_build_filename (physical_uri + 7, "addressbook.db", NULL);
- summary_path = g_build_filename (physical_uri + 7, "addressbook.db.summary", NULL);
- rv = unlink (db_path);
-
- if (rv == 0 || (rv == -1 && errno == ENOENT))
- rv = unlink (summary_path);
+ ESource *selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (selector));
- if (rv == 0 || (rv == -1 && errno == ENOENT)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_OK,
- &ev);
- }
- else {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED,
- &ev);
+ if (selected_source != NULL) {
+ char *uri = e_source_get_uri (selected_source);
+ bonobo_control_set_property (view_control, NULL, "folder_uri", TC_CORBA_string, uri, NULL);
+ g_free (uri);
}
-
- g_free (db_path);
- g_free (summary_path);
-
- CORBA_exception_free(&ev);
}
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-/* This code is cut & pasted from calendar/gui/component-factory.c */
+/* Callbacks. */
-static GNOME_Evolution_ShellComponentListener_Result
-xfer_file (GnomeVFSURI *base_src_uri,
- GnomeVFSURI *base_dest_uri,
- const char *file_name,
- int remove_source)
+static void
+primary_source_selection_changed_callback (ESourceSelector *selector,
+ BonoboControl *view_control)
{
- GnomeVFSURI *src_uri, *dest_uri;
- GnomeVFSHandle *hin, *hout;
- GnomeVFSResult result;
- GnomeVFSFileInfo file_info;
- GnomeVFSFileSize size;
- char *buffer;
-
- src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name);
-
- result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ);
- if (result == GNOME_VFS_ERROR_NOT_FOUND) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */
- }
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+ load_uri_for_selection (selector, view_control);
+}
- result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
- dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name);
+/* Evolution::Component CORBA methods. */
- result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+static void
+impl_createControls (PortableServer_Servant servant,
+ Bonobo_Control *corba_sidebar_control,
+ Bonobo_Control *corba_view_control,
+ CORBA_Environment *ev)
+{
+ AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant));
+ GtkWidget *selector;
+ GtkWidget *selector_scrolled_window;
+ BonoboControl *sidebar_control;
+ BonoboControl *view_control;
- /* write source file to destination file */
- buffer = g_malloc (file_info.size);
- result = gnome_vfs_read (hin, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+ selector = e_source_selector_new (addressbook_component->priv->source_list);
+ e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE);
+ gtk_widget_show (selector);
- result = gnome_vfs_write (hout, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+ selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (selector_scrolled_window), selector);
+ gtk_widget_show (selector_scrolled_window);
- if (remove_source) {
- char *text_uri;
+ sidebar_control = bonobo_control_new (selector_scrolled_window);
- /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */
+ view_control = addressbook_new_control ();
+ g_signal_connect_object (selector, "primary_selection_changed",
+ G_CALLBACK (primary_source_selection_changed_callback),
+ G_OBJECT (view_control), 0);
+ load_uri_for_selection (E_SOURCE_SELECTOR (selector), view_control);
- text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE);
- result = gnome_vfs_unlink (text_uri);
- g_free (text_uri);
- }
+ *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev);
+ *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev);
+}
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_OK;
-}
+/* GObject methods. */
static void
-xfer_folder (EvolutionShellComponent *shell_component,
- const char *source_physical_uri,
- const char *destination_physical_uri,
- const char *type,
- gboolean remove_source,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+impl_dispose (GObject *object)
{
- CORBA_Environment ev;
-
- GnomeVFSURI *src_uri;
- GnomeVFSURI *dest_uri;
- GnomeVFSResult result;
- GNOME_Evolution_ShellComponentListener_Result e_result;
-
- CORBA_exception_init (&ev);
-
- if (!IS_CONTACT_TYPE (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
-
- if (!strncmp (source_physical_uri, "ldap://", 7)
- || !strncmp (destination_physical_uri, "ldap://", 7)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_OPERATION,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
-
- if (strncmp (source_physical_uri, "file://", 7)
- || strncmp (destination_physical_uri, "file://", 7)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- CORBA_exception_free(&ev);
- return;
- }
+ AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv;
- /* check URIs */
- src_uri = gnome_vfs_uri_new (source_physical_uri);
- dest_uri = gnome_vfs_uri_new (destination_physical_uri);
- if (!src_uri || ! dest_uri) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- CORBA_exception_free (&ev);
- return;
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
}
- e_result = xfer_file (src_uri, dest_uri, "addressbook.db", remove_source);
-
- if ((e_result == GNOME_Evolution_ShellComponentListener_OK) && remove_source) {
- char *summary_uri;
-
- summary_uri = g_strconcat (source_physical_uri, "/addressbook.db.summary", NULL);
- result = gnome_vfs_unlink (summary_uri);
- if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_NOT_FOUND)
- e_result = GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- g_free (summary_uri);
+ if (priv->gconf_client != NULL) {
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
}
- GNOME_Evolution_ShellComponentListener_notifyResult (listener, e_result, &ev);
-
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
-
- CORBA_exception_free (&ev);
-}
-
-static char*
-get_dnd_selection (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- int type,
- int *format_return,
- const char **selection_return,
- int *selection_length_return,
- void *closure)
-{
- /* g_print ("should get dnd selection for %s\n", physical_uri); */
- return NULL;
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
-static int owner_count = 0;
-
static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
+impl_finalize (GObject *object)
{
- owner_count ++;
+ AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv;
- if (global_shell_client == NULL)
- global_shell_client = shell_client;
+ g_free (priv);
- addressbook_storage_setup (shell_component, evolution_homedir);
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- GNOME_Evolution_Shell shell_interface,
- gpointer user_data)
-{
- owner_count --;
-
- if (owner_count == 0)
- global_shell_client = NULL;
- addressbook_storage_cleanup ();
-}
+/* Initialization. */
-/* FIXME We should perhaps take the time to figure out if the book is editable. */
static void
-new_item_cb (EBook *book, gpointer closure)
+addressbook_component_class_init (AddressbookComponentClass *class)
{
- gboolean is_list = GPOINTER_TO_INT (closure);
- ECard *card;
-
- if (book == NULL)
- return;
-
- card = e_card_new ("");
- if (is_list)
- e_addressbook_show_contact_list_editor (book, card, TRUE, TRUE);
- else
- e_addressbook_show_contact_editor (book, card, TRUE, TRUE);
- g_object_unref (card);
-}
+ POA_GNOME_Evolution_Component__epv *epv = &class->epv;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
-static void
-user_create_new_item_cb (EvolutionShellComponent *shell_component,
- const char *id,
- const char *parent_folder_physical_uri,
- const char *parent_folder_type,
- gpointer data)
-{
- gboolean is_contact_list;
- if (!strcmp (id, "contact")) {
- is_contact_list = FALSE;
- } else if (!strcmp (id, "contact_list")) {
- is_contact_list = TRUE;
- } else {
- g_warning ("Don't know how to create item of type \"%s\"", id);
- return;
- }
- if (IS_CONTACT_TYPE (parent_folder_type)) {
- e_book_use_address_book_by_uri (parent_folder_physical_uri,
- new_item_cb, GINT_TO_POINTER (is_contact_list));
- } else {
- e_book_use_default_book (new_item_cb, GINT_TO_POINTER (is_contact_list));
- }
-}
+ epv->createControls = impl_createControls;
-
-/* Destination side DnD */
+ object_class->dispose = impl_dispose;
+ object_class->finalize = impl_finalize;
-static CORBA_boolean
-destination_folder_handle_motion (EvolutionShellComponentDndDestinationFolder *folder,
- const char *physical_uri,
- const char *folder_type,
- const GNOME_Evolution_ShellComponentDnd_DestinationFolder_Context * destination_context,
- GNOME_Evolution_ShellComponentDnd_Action * suggested_action_return,
- gpointer user_data)
-{
- *suggested_action_return = GNOME_Evolution_ShellComponentDnd_ACTION_MOVE;
- return TRUE;
+ parent_class = g_type_class_peek_parent (class);
}
static void
-dnd_drop_book_open_cb (EBook *book, EBookStatus status, GList *card_list)
-{
- GList *l;
-
- for (l = card_list; l; l = l->next) {
- ECard *card = l->data;
-
- e_card_merging_book_add_card (book, card, NULL /* XXX */, NULL);
- }
-}
-
-static CORBA_boolean
-destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *folder,
- const char *physical_uri,
- const char *folder_type,
- const GNOME_Evolution_ShellComponentDnd_DestinationFolder_Context * destination_context,
- const GNOME_Evolution_ShellComponentDnd_Action action,
- const GNOME_Evolution_ShellComponentDnd_Data * data,
- gpointer user_data)
+addressbook_component_init (AddressbookComponent *component)
{
- EBook *book;
- GList *card_list;
- char *expanded_uri;
-
- if (action == GNOME_Evolution_ShellComponentDnd_ACTION_LINK)
- return FALSE; /* we can't create links in our addressbook format */
-
- /* g_print ("in destination_folder_handle_drop (%s)\n", physical_uri); */
-
- card_list = e_card_load_cards_from_string_with_default_charset (data->bytes._buffer, "ISO-8859-1");
-
- expanded_uri = e_book_expand_uri (physical_uri);
+ AddressbookComponentPrivate *priv;
- book = e_book_new ();
- addressbook_load_uri (book, expanded_uri,
- (EBookCallback)dnd_drop_book_open_cb, card_list);
+ priv = g_new0 (AddressbookComponentPrivate, 1);
- g_free (expanded_uri);
+ /* EPFIXME: Should use a custom one instead? Also we should add
+ addressbook_component_peek_gconf_client(). */
+ priv->gconf_client = gconf_client_get_default ();
- return TRUE;
-}
-
-
-/* Quitting. */
+ priv->source_list = e_source_list_new_for_gconf (priv->gconf_client,
+ "/apps/evolution/addressbook/sources");
-static gboolean
-request_quit (EvolutionShellComponent *shell_component,
- void *data)
-{
- if (! e_contact_editor_request_close_all ()
- || ! e_contact_list_editor_request_close_all ())
- return FALSE;
- else
- return TRUE;
+ component->priv = priv;
}
-
-/* The factory function. */
-
-static void
-add_creatable_item (EvolutionShellComponent *shell_component,
- const char *id,
- const char *description,
- const char *menu_description,
- const char *tooltip,
- char menu_shortcut,
- const char *icon_name)
-{
- char *icon_path;
- GdkPixbuf *icon;
-
- if (icon_name == NULL) {
- icon_path = NULL;
- icon = NULL;
- } else {
- icon_path = g_build_filename (EVOLUTION_IMAGESDIR, icon_name, NULL);
- icon = gdk_pixbuf_new_from_file (icon_path, NULL);
- }
-
- evolution_shell_component_add_user_creatable_item (shell_component,
- id,
- description,
- menu_description,
- tooltip,
- "contacts",
- menu_shortcut,
- icon);
-
- if (icon != NULL)
- gdk_pixbuf_unref (icon);
- g_free (icon_path);
-}
+/* Public API. */
-static BonoboObject *
-create_component (void)
+AddressbookComponent *
+addressbook_component_peek (void)
{
- EvolutionShellComponent *shell_component;
- EvolutionShellComponentDndDestinationFolder *destination_interface;
-
- shell_component = evolution_shell_component_new (folder_types, NULL,
- create_view, create_folder,
- remove_folder, xfer_folder,
- NULL, NULL,
- get_dnd_selection,
- request_quit,
- NULL);
-
- destination_interface = evolution_shell_component_dnd_destination_folder_new (destination_folder_handle_motion,
- destination_folder_handle_drop,
- shell_component);
-
- bonobo_object_add_interface (BONOBO_OBJECT (shell_component),
- BONOBO_OBJECT (destination_interface));
-
- add_creatable_item (shell_component, "contact",
- _("New Contact"), _("_Contact"),
- _("Create a new contact"), 'c',
- "evolution-contacts-mini.png");
- add_creatable_item (shell_component, "contact_list",
- _("New Contact List"), _("Contact _List"),
- _("Create a new contact list"), 'l',
- "contact-list-16.png");
-
- g_signal_connect (shell_component, "owner_set",
- G_CALLBACK (owner_set_cb), NULL);
- g_signal_connect (shell_component, "owner_unset",
- G_CALLBACK (owner_unset_cb), NULL);
- g_signal_connect (shell_component, "user_create_new_item",
- G_CALLBACK (user_create_new_item_cb), NULL);
-
- return BONOBO_OBJECT (shell_component);
-}
+ static AddressbookComponent *component = NULL;
-static void
-ensure_completion_uris_exist()
-{
- /* Initialize the completion uris if they aren't set yet. The
- default set is just the local Contacts folder. */
- EConfigListener *db;
- char *val;
-
- db = e_book_get_config_database ();
-
- val = e_config_listener_get_string (db, "/apps/evolution/addressbook/completion/uris");
-
- if (val && !*val) {
- g_free (val);
- val = NULL;
- }
-
- if (!val) {
- EFolderListItem f[2];
- char *dirname, *uri;
- /* in the case where the user is running for the first
- time, populate the list with the local contact
- folder */
- dirname = g_build_filename (g_get_home_dir (), "evolution/local/Contacts", NULL);
- uri = g_strdup_printf ("file://%s", dirname);
-
- f[0].uri = "evolution:/local/Contacts";
- f[0].physical_uri = uri;
- f[0].display_name = _("Contacts");
-
- memset (&f[1], 0, sizeof (f[1]));
-
- val = e_folder_list_create_xml (f);
-
- g_free (dirname);
- g_free (uri);
- e_config_listener_set_string (db, "/apps/evolution/addressbook/completion/uris", val);
- }
+ if (component == NULL)
+ component = g_object_new (addressbook_component_get_type (), NULL);
- g_free (val);
+ return component;
}
-
-/* FIXME this is wrong. */
-BonoboObject *
-addressbook_component_init (void)
-{
- ensure_completion_uris_exist ();
- return create_component ();
-}
+BONOBO_TYPE_FUNC_FULL (AddressbookComponent, GNOME_Evolution_Component, PARENT_TYPE, addressbook_component)
diff --git a/addressbook/gui/component/addressbook-component.h b/addressbook/gui/component/addressbook-component.h
index 4c6f0cdd8b..bf72a431d8 100644
--- a/addressbook/gui/component/addressbook-component.h
+++ b/addressbook/gui/component/addressbook-component.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* addressbook-component.h
*
- * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2003 Ximian, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -17,16 +17,43 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * Author: Ettore Perazzoli
+ * Author: Ettore Perazzoli <ettore@ximian.com>
*/
-#ifndef _ADDRESSBOOK_COMPONENT_H
-#define _ADDRESSBOOK_COMPONENT_H
+#ifndef _ADDRESSBOOK_COMPONENT_H_
+#define _ADDRESSBOOK_COMPONENT_H_
-#include "evolution-shell-component.h"
-#include "evolution-storage.h"
+#include <bonobo/bonobo-object.h>
-BonoboObject *addressbook_component_init (void);
-EvolutionShellClient *addressbook_component_get_shell_client (void);
+#include "Evolution.h"
-#endif /* _ADDRESSBOOK_COMPONENT_H */
+#define ADDRESSBOOK_TYPE_COMPONENT (addressbook_component_get_type ())
+#define ADDRESSBOOK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponent))
+#define ADDRESSBOOK_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponentClass))
+#define ADDRESSBOOK_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT))
+#define ADDRESSBOOK_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT))
+
+
+typedef struct _AddressbookComponent AddressbookComponent;
+typedef struct _AddressbookComponentPrivate AddressbookComponentPrivate;
+typedef struct _AddressbookComponentClass AddressbookComponentClass;
+
+struct _AddressbookComponent {
+ BonoboObject parent;
+
+ AddressbookComponentPrivate *priv;
+};
+
+struct _AddressbookComponentClass {
+ BonoboObjectClass parent_class;
+
+ POA_GNOME_Evolution_Component__epv epv;
+};
+
+
+GType addressbook_component_get_type (void);
+
+AddressbookComponent *addressbook_component_peek (void);
+
+
+#endif /* _ADDRESSBOOK_COMPONENT_H_ */
diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c
index e2855ac7f4..c5fc9c127a 100644
--- a/addressbook/gui/component/addressbook-config.c
+++ b/addressbook/gui/component/addressbook-config.c
@@ -107,7 +107,6 @@ struct _AddressbookDialog {
GtkWidget *page;
GladeXML *gui;
- GNOME_Evolution_Shell shell;
GtkWidget *sourcesTable;
GtkTreeModel *sourcesModel;
@@ -1555,7 +1554,7 @@ sources_table_row_activated (GtkTreeView *tree_view, GtkTreePath *path,
static AddressbookDialog *
-ldap_dialog_new (GNOME_Evolution_Shell shell)
+ldap_dialog_new (void)
{
AddressbookDialog *dialog;
GList *l;
@@ -1564,7 +1563,6 @@ ldap_dialog_new (GNOME_Evolution_Shell shell)
dialog = g_new0 (AddressbookDialog, 1);
dialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL, NULL);
- dialog->shell = shell;
scrolled = glade_xml_get_widget (dialog->gui, "sourcesTable");
dialog->sourcesTable = g_object_get_data (G_OBJECT (scrolled), "table");
@@ -1657,7 +1655,7 @@ addressbook_dialog_create_sources_table (char *name, char *string1, char *string
#endif /* HAVE_LDAP */
static EvolutionConfigControl *
-ldap_config_control_new (GNOME_Evolution_Shell shell)
+ldap_config_control_new (void)
{
GtkWidget *control_widget;
EvolutionConfigControl *control;
@@ -1665,7 +1663,7 @@ ldap_config_control_new (GNOME_Evolution_Shell shell)
#ifdef HAVE_LDAP
AddressbookDialog *dialog;
- dialog = ldap_dialog_new (shell);
+ dialog = ldap_dialog_new ();
control_widget = dialog->page;
@@ -1697,13 +1695,7 @@ ldap_config_control_new (GNOME_Evolution_Shell shell)
EvolutionConfigControl *
addressbook_config_control_new (void)
{
- GNOME_Evolution_Shell shell;
-
- shell = evolution_shell_client_corba_objref (addressbook_component_get_shell_client ());
- if (! shell)
- return NULL;
-
- return ldap_config_control_new (shell);
+ return ldap_config_control_new ();
}
void
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
index b21c70a83d..32c5ab1288 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/gui/component/addressbook.c
@@ -24,7 +24,6 @@
#include <string.h>
#include <glib.h>
-#include <gtk/gtkframe.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkmessagedialog.h>
@@ -41,23 +40,20 @@
#include "e-util/e-categories-master-list-wombat.h"
#include "e-util/e-sexp.h"
#include "e-util/e-passwords.h"
-#include "select-names/e-select-names.h"
-#include "select-names/e-select-names-manager.h"
#include "evolution-shell-component-utils.h"
#include "evolution-activity-client.h"
#include "e-contact-editor.h"
-#include "e-contact-save-as.h"
#include "addressbook-config.h"
#include "addressbook.h"
#include "addressbook-component.h"
#include "addressbook/gui/search/e-addressbook-search-dialog.h"
#include "addressbook/gui/widgets/e-addressbook-view.h"
-#include "addressbook/gui/widgets/e-addressbook-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
#include "addressbook/printing/e-contact-print.h"
+#include "addressbook/util/eab-book-util.h"
-#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
+#include <ebook/e-book-async.h>
#include <widgets/misc/e-search-bar.h>
#include <widgets/misc/e-filter-bar.h>
@@ -73,7 +69,7 @@ static GdkPixbuf *progress_icon[2] = { NULL, NULL };
typedef struct {
gint refs;
- EAddressbookView *view;
+ EABView *view;
ESearchBar *search;
gint ecml_changed_id;
GtkWidget *vbox;
@@ -100,7 +96,7 @@ save_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_save_as(view->view);
+ eab_view_save_as(view->view);
}
static void
@@ -108,7 +104,7 @@ view_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_view(view->view);
+ eab_view_view(view->view);
}
static void
@@ -117,7 +113,7 @@ search_cb (BonoboUIComponent *uih, void *user_data, const char *path)
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- gtk_widget_show(e_addressbook_search_dialog_new(view->view));
+ gtk_widget_show(eab_search_dialog_new(view->view));
}
static void
@@ -125,7 +121,7 @@ delete_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view) {
- e_addressbook_view_delete_selection(view->view);
+ eab_view_delete_selection(view->view);
}
}
@@ -134,7 +130,7 @@ print_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_print(view->view);
+ eab_view_print(view->view);
}
static void
@@ -142,7 +138,7 @@ print_preview_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_print_preview(view->view);
+ eab_view_print_preview(view->view);
}
static void
@@ -150,7 +146,7 @@ stop_loading_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_stop(view->view);
+ eab_view_stop(view->view);
}
static void
@@ -158,7 +154,7 @@ cut_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_cut(view->view);
+ eab_view_cut(view->view);
}
static void
@@ -166,7 +162,7 @@ copy_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_copy(view->view);
+ eab_view_copy(view->view);
}
static void
@@ -174,7 +170,7 @@ paste_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_paste(view->view);
+ eab_view_paste(view->view);
}
static void
@@ -182,7 +178,7 @@ select_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *pat
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_select_all (view->view);
+ eab_view_select_all (view->view);
}
static void
@@ -190,7 +186,7 @@ send_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_send (view->view);
+ eab_view_send (view->view);
}
static void
@@ -198,7 +194,7 @@ send_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_send_to (view->view);
+ eab_view_send_to (view->view);
}
static void
@@ -206,7 +202,7 @@ copy_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_copy_to_folder (view->view);
+ eab_view_copy_to_folder (view->view);
}
static void
@@ -214,7 +210,7 @@ move_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
if (view->view)
- e_addressbook_view_move_to_folder (view->view);
+ eab_view_move_to_folder (view->view);
}
static void
@@ -224,7 +220,7 @@ forget_passwords_cb (BonoboUIComponent *uih, void *user_data, const char *path)
}
static void
-update_command_state (EAddressbookView *eav, AddressbookView *view)
+update_command_state (EABView *eav, AddressbookView *view)
{
BonoboUIComponent *uic;
@@ -239,78 +235,78 @@ update_command_state (EAddressbookView *eav, AddressbookView *view)
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSaveAsVCard",
"sensitive",
- e_addressbook_view_can_save_as (view->view) ? "1" : "0", NULL);
+ eab_view_can_save_as (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsView",
"sensitive",
- e_addressbook_view_can_view (view->view) ? "1" : "0", NULL);
+ eab_view_can_view (view->view) ? "1" : "0", NULL);
/* Print Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPrint",
"sensitive",
- e_addressbook_view_can_print (view->view) ? "1" : "0", NULL);
+ eab_view_can_print (view->view) ? "1" : "0", NULL);
/* Print Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPrintPreview",
"sensitive",
- e_addressbook_view_can_print (view->view) ? "1" : "0", NULL);
+ eab_view_can_print (view->view) ? "1" : "0", NULL);
/* Delete Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactDelete",
"sensitive",
- e_addressbook_view_can_delete (view->view) ? "1" : "0", NULL);
+ eab_view_can_delete (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCut",
"sensitive",
- e_addressbook_view_can_cut (view->view) ? "1" : "0", NULL);
+ eab_view_can_cut (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCopy",
"sensitive",
- e_addressbook_view_can_copy (view->view) ? "1" : "0", NULL);
+ eab_view_can_copy (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPaste",
"sensitive",
- e_addressbook_view_can_paste (view->view) ? "1" : "0", NULL);
+ eab_view_can_paste (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSelectAll",
"sensitive",
- e_addressbook_view_can_select_all (view->view) ? "1" : "0", NULL);
+ eab_view_can_select_all (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSendContactToOther",
"sensitive",
- e_addressbook_view_can_send (view->view) ? "1" : "0", NULL);
+ eab_view_can_send (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSendMessageToContact",
"sensitive",
- e_addressbook_view_can_send_to (view->view) ? "1" : "0", NULL);
+ eab_view_can_send_to (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsMoveToFolder",
"sensitive",
- e_addressbook_view_can_move_to_folder (view->view) ? "1" : "0", NULL);
+ eab_view_can_move_to_folder (view->view) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCopyToFolder",
"sensitive",
- e_addressbook_view_can_copy_to_folder (view->view) ? "1" : "0", NULL);
+ eab_view_can_copy_to_folder (view->view) ? "1" : "0", NULL);
/* Stop */
bonobo_ui_component_set_prop (uic,
"/commands/ContactStop",
"sensitive",
- e_addressbook_view_can_stop (view->view) ? "1" : "0", NULL);
+ eab_view_can_stop (view->view) ? "1" : "0", NULL);
}
addressbook_view_unref (view);
}
static void
-change_view_type (AddressbookView *view, EAddressbookViewType view_type)
+change_view_type (AddressbookView *view, EABViewType view_type)
{
g_object_set (view->view, "type", view_type, NULL);
}
@@ -379,7 +375,7 @@ control_activate (BonoboControl *control,
EVOLUTION_UIDIR "/evolution-addressbook.xml",
"evolution-addressbook", NULL);
- e_addressbook_view_setup_menus (view->view, uic);
+ eab_view_setup_menus (view->view, uic);
e_pixmaps_update (uic, pixmaps);
@@ -401,25 +397,21 @@ control_activate_cb (BonoboControl *control,
if (activate) {
control_activate (control, uic, view);
if (activate && view->view && view->view->model)
- e_addressbook_model_force_folder_bar_message (view->view->model);
+ eab_model_force_folder_bar_message (view->view->model);
/* if the book failed to load, we kick off another
load here */
if (view->failed_to_load && view->uri) {
EBook *book;
- char *uri_data;
book = e_book_new ();
- uri_data = e_book_expand_uri (view->uri);
- addressbook_load_uri (book, uri_data, book_open_cb, view);
-
- g_free(uri_data);
+ addressbook_load_uri (book, view->uri, book_open_cb, view);
}
} else {
bonobo_ui_component_unset_container (uic, NULL);
- e_addressbook_view_discard_menus (view->view);
+ eab_view_discard_menus (view->view);
}
}
@@ -482,7 +474,7 @@ book_open_cb (EBook *book, EBookStatus status, gpointer closure)
{
AddressbookView *view = closure;
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
view->failed_to_load = FALSE;
g_object_set(view->view,
"book", book,
@@ -596,8 +588,8 @@ load_uri_auth_cb (EBook *book, EBookStatus status, gpointer closure)
{
LoadUriData *data = closure;
- if (status != E_BOOK_STATUS_SUCCESS) {
- if (status == E_BOOK_STATUS_CANCELLED) {
+ if (status != E_BOOK_ERROR_OK) {
+ if (status == E_BOOK_ERROR_CANCELLED) {
/* the user clicked cancel in the password dialog */
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL,
@@ -607,7 +599,7 @@ load_uri_auth_cb (EBook *book, EBookStatus status, gpointer closure)
_("Accessing LDAP Server anonymously"));
g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
- data->cb (book, E_BOOK_STATUS_SUCCESS, data->closure);
+ data->cb (book, E_BOOK_ERROR_OK, data->closure);
g_free (data->clean_uri);
g_free (data);
return;
@@ -682,15 +674,15 @@ addressbook_authenticate (EBook *book, gboolean previous_failure, AddressbookSou
user = source->email_addr;
if (!user)
user = "";
- e_book_authenticate_user (book, user, password ? password : pass_dup,
- addressbook_storage_auth_type_to_string (source->auth),
- cb, closure);
+ e_book_async_authenticate_user (book, user, password ? password : pass_dup,
+ addressbook_storage_auth_type_to_string (source->auth),
+ cb, closure);
g_free (pass_dup);
return;
}
else {
/* they hit cancel */
- cb (book, E_BOOK_STATUS_CANCELLED, closure);
+ cb (book, E_BOOK_ERROR_CANCELLED, closure);
}
}
@@ -699,7 +691,7 @@ load_uri_cb (EBook *book, EBookStatus status, gpointer closure)
{
LoadUriData *load_uri_data = closure;
- if (status == E_BOOK_STATUS_SUCCESS && book != NULL) {
+ if (status == E_BOOK_ERROR_OK && book != NULL) {
/* check if the addressbook needs authentication */
@@ -728,18 +720,18 @@ addressbook_load_uri (EBook *book, const char *uri,
load_uri_data->cb = cb;
load_uri_data->closure = closure;
- e_book_load_uri (book, uri, load_uri_cb, load_uri_data);
+ e_book_async_load_uri (book, uri, load_uri_cb, load_uri_data);
}
void
-addressbook_load_default_book (EBook *book, EBookCallback cb, gpointer closure)
+addressbook_load_default_book (EBookCallback cb, gpointer closure)
{
LoadUriData *load_uri_data = g_new (LoadUriData, 1);
load_uri_data->cb = cb;
load_uri_data->closure = closure;
- e_book_load_default_book (book, load_uri_cb, load_uri_data);
+ e_book_async_get_default_addressbook (load_uri_cb, load_uri_data);
}
static void
@@ -751,14 +743,12 @@ set_prop (BonoboPropertyBag *bag,
{
AddressbookView *view = user_data;
- char *uri_data;
-
switch (arg_id) {
case PROPERTY_FOLDER_URI_IDX:
if (view->uri) {
/* we've already had a uri set on this view, so unload it */
- e_book_unload_uri (view->book);
+ e_book_async_unload_uri (view->book);
g_free (view->uri);
} else {
view->book = e_book_new ();
@@ -768,11 +758,7 @@ set_prop (BonoboPropertyBag *bag,
view->uri = g_strdup(BONOBO_ARG_GET_STRING (arg));
- uri_data = e_book_expand_uri (view->uri);
-
- addressbook_load_uri (view->book, uri_data, book_open_cb, view);
-
- g_free(uri_data);
+ addressbook_load_uri (view->book, view->uri, book_open_cb, view);
break;
@@ -800,19 +786,6 @@ static ESearchBarItem addressbook_search_option_items[] = {
};
static void
-alphabet_state_changed (EAddressbookView *eav, gunichar letter, AddressbookView *view)
-{
- view->ignore_search_changes = TRUE;
- if (letter == 0) {
- e_search_bar_set_item_id (view->search, ESB_FULL_NAME);
- e_search_bar_set_text (view->search, "");
- } else {
- e_search_bar_set_item_id (view->search, ESB_FULL_NAME);
- }
- view->ignore_search_changes = FALSE;
-}
-
-static void
addressbook_search_activated (ESearchBar *esb, AddressbookView *view)
{
ECategoriesMasterList *master_list;
@@ -830,7 +803,7 @@ addressbook_search_activated (ESearchBar *esb, AddressbookView *view)
NULL);
if (search_type == ESB_ADVANCED) {
- gtk_widget_show(e_addressbook_search_dialog_new(view->view));
+ gtk_widget_show(eab_search_dialog_new(view->view));
}
else {
if ((search_word && strlen (search_word)) || search_type == ESB_CATEGORY) {
@@ -890,7 +863,7 @@ addressbook_query_changed (ESearchBar *esb, AddressbookView *view)
NULL);
if (search_type == ESB_ADVANCED) {
- gtk_widget_show(e_addressbook_search_dialog_new(view->view));
+ gtk_widget_show(eab_search_dialog_new(view->view));
}
}
@@ -916,7 +889,7 @@ retrieve_shell_view_interface_from_control (BonoboControl *control)
}
static void
-set_status_message (EAddressbookView *eav, const char *message, AddressbookView *view)
+set_status_message (EABView *eav, const char *message, AddressbookView *view)
{
if (!message || !*message) {
@@ -925,6 +898,7 @@ set_status_message (EAddressbookView *eav, const char *message, AddressbookView
view->activity = NULL;
}
}
+#if 0 /* EPFIXME */
else if (!view->activity) {
int display;
char *clientid = g_strdup_printf ("%p", view);
@@ -937,6 +911,7 @@ set_status_message (EAddressbookView *eav, const char *message, AddressbookView
g_free (clientid);
}
+#endif
else {
evolution_activity_client_update (view->activity, message, -1.0);
}
@@ -944,12 +919,12 @@ set_status_message (EAddressbookView *eav, const char *message, AddressbookView
}
static void
-search_result (EAddressbookView *eav, EBookViewStatus status, AddressbookView *view)
+search_result (EABView *eav, EBookViewStatus status, AddressbookView *view)
{
char *str = NULL;
switch (status) {
- case E_BOOK_VIEW_STATUS_SUCCESS:
+ case E_BOOK_VIEW_STATUS_OK:
return;
case E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED:
str = _("More cards matched this query than either the server is \n"
@@ -963,14 +938,13 @@ search_result (EAddressbookView *eav, EBookViewStatus status, AddressbookView *v
"more specific or raise the time limit in the directory server\n"
"preferences for this addressbook.");
break;
- case E_BOOK_VIEW_STATUS_INVALID_QUERY:
+ case E_BOOK_VIEW_ERROR_INVALID_QUERY:
str = _("The backend for this addressbook was unable to parse this query.");
break;
- case E_BOOK_VIEW_STATUS_QUERY_REFUSED:
+ case E_BOOK_VIEW_ERROR_QUERY_REFUSED:
str = _("The backend for this addressbook refused to perform this query.");
break;
- case E_BOOK_VIEW_STATUS_OTHER_ERROR:
- case E_BOOK_VIEW_STATUS_UNKNOWN:
+ case E_BOOK_VIEW_ERROR_OTHER_ERROR:
str = _("This query did not complete successfully.");
break;
}
@@ -988,7 +962,7 @@ search_result (EAddressbookView *eav, EBookViewStatus status, AddressbookView *v
}
static void
-set_folder_bar_label (EAddressbookView *eav, const char *message, AddressbookView *view)
+set_folder_bar_label (EABView *eav, const char *message, AddressbookView *view)
{
CORBA_Environment ev;
GNOME_Evolution_ShellView shell_view_interface;
@@ -1023,18 +997,6 @@ set_folder_bar_label (EAddressbookView *eav, const char *message, AddressbookVie
bonobo_object_release_unref (shell_view_interface, NULL);
}
-/* Our global singleton config database */
-static Bonobo_ConfigDatabase config_db = NULL;
-
-Bonobo_ConfigDatabase
-addressbook_config_database (CORBA_Environment *ev)
-{
- if (config_db == NULL)
- config_db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", ev);
-
- return config_db;
-}
-
static int
compare_subitems (const void *a, const void *b)
{
@@ -1098,10 +1060,6 @@ BonoboControl *
addressbook_new_control (void)
{
AddressbookView *view;
- GtkWidget *frame;
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
view = g_new0 (AddressbookView, 1);
view->refs = 1;
@@ -1125,15 +1083,13 @@ addressbook_new_control (void)
g_signal_connect (view->search, "search_activated",
G_CALLBACK (addressbook_search_activated), view);
- view->view = E_ADDRESSBOOK_VIEW(e_addressbook_view_new());
- gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (view->view));
- gtk_box_pack_start (GTK_BOX (view->vbox), frame,
+ view->view = EAB_VIEW(eab_view_new());
+ gtk_box_pack_start (GTK_BOX (view->vbox), GTK_WIDGET (view->view),
TRUE, TRUE, 0);
/* create the initial view */
- change_view_type (view, E_ADDRESSBOOK_VIEW_MINICARD);
+ change_view_type (view, EAB_VIEW_TABLE);
- gtk_widget_show (frame);
gtk_widget_show (view->vbox);
gtk_widget_show (GTK_WIDGET(view->view));
gtk_widget_show (GTK_WIDGET(view->search));
@@ -1142,36 +1098,24 @@ addressbook_new_control (void)
bonobo_property_bag_add (view->properties,
PROPERTY_FOLDER_URI, PROPERTY_FOLDER_URI_IDX,
- BONOBO_ARG_STRING, NULL, _("The URI that the Folder Browser will display"), 0);
+ BONOBO_ARG_STRING, NULL,
+ _("URI of the contacts that the control will display"), 0);
bonobo_control_set_properties (view->control,
bonobo_object_corba_objref (BONOBO_OBJECT (view->properties)),
NULL);
- g_signal_connect (view->view,
- "status_message",
- G_CALLBACK(set_status_message),
- view);
-
- g_signal_connect (view->view,
- "search_result",
- G_CALLBACK(search_result),
- view);
-
- g_signal_connect (view->view,
- "folder_bar_message",
- G_CALLBACK(set_folder_bar_label),
- view);
-
- g_signal_connect (view->view,
- "command_state_change",
- G_CALLBACK(update_command_state),
- view);
-
- g_signal_connect (view->view,
- "alphabet_state_change",
- G_CALLBACK(alphabet_state_changed),
- view);
+ g_signal_connect (view->view, "status_message",
+ G_CALLBACK(set_status_message), view);
+
+ g_signal_connect (view->view, "search_result",
+ G_CALLBACK(search_result), view);
+
+ g_signal_connect (view->view, "folder_bar_message",
+ G_CALLBACK(set_folder_bar_label), view);
+
+ g_signal_connect (view->view, "command_state_change",
+ G_CALLBACK(update_command_state), view);
view->uri = NULL;
diff --git a/addressbook/gui/component/addressbook.h b/addressbook/gui/component/addressbook.h
index 3d4bba5187..573adbf38d 100644
--- a/addressbook/gui/component/addressbook.h
+++ b/addressbook/gui/component/addressbook.h
@@ -5,12 +5,12 @@
#include <e-util/e-config-listener.h>
#include <bonobo/bonobo-object.h>
#include <bonobo/bonobo-moniker-util.h>
-#include <ebook/e-book.h>
+#include <ebook/e-book-async.h>
/* use this instead of e_book_load_uri everywhere where you want the
authentication to be handled for you. */
void addressbook_load_uri (EBook *book, const char *uri, EBookCallback cb, gpointer closure);
-void addressbook_load_default_book (EBook *book, EBookCallback open_response, gpointer closure);
+void addressbook_load_default_book (EBookCallback open_response, gpointer closure);
BonoboControl *addressbook_new_control (void);
diff --git a/addressbook/gui/component/component-factory.c b/addressbook/gui/component/component-factory.c
index 9d5e946dc0..512ab72f2a 100644
--- a/addressbook/gui/component/component-factory.c
+++ b/addressbook/gui/component/component-factory.c
@@ -26,20 +26,18 @@
#include "addressbook.h"
#include "addressbook-component.h"
#include "addressbook-config.h"
-#include "e-address-popup.h"
-#include "e-address-widget.h"
-#include "e-minicard-control.h"
+#include "eab-popup-control.h"
+#include "eab-vcard-control.h"
#include "select-names/e-select-names-bonobo.h"
#include <bonobo/bonobo-shlib-factory.h>
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_Factory"
+#define FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_Factory_2"
-#define MINICARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_MiniCard_Control"
+#define VCARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_VCard_Control"
#define ADDRESSBOOK_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_Control"
-#define SHELL_COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_ShellComponent"
-#define ADDRESS_WIDGET_ID "OAFIID:GNOME_Evolution_Addressbook_AddressWidget"
+#define COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_Component"
#define ADDRESS_POPUP_ID "OAFIID:GNOME_Evolution_Addressbook_AddressPopup"
#define SELECT_NAMES_ID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
#define LDAP_STORAGE_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl"
@@ -50,16 +48,19 @@ factory (BonoboGenericFactory *factory,
const char *component_id,
void *closure)
{
- if (strcmp (component_id, MINICARD_CONTROL_ID) == 0)
- return BONOBO_OBJECT (e_minicard_control_new ());
+ printf ("asked to activate component_id `%s'\n", component_id);
+
+ if (strcmp (component_id, VCARD_CONTROL_ID) == 0)
+ return BONOBO_OBJECT (eab_vcard_control_new ());
if (strcmp (component_id, ADDRESSBOOK_CONTROL_ID) == 0)
return BONOBO_OBJECT (addressbook_new_control ());
- if (strcmp (component_id, SHELL_COMPONENT_ID) == 0)
- return addressbook_component_init ();
- if (strcmp (component_id, ADDRESS_WIDGET_ID) == 0)
- return BONOBO_OBJECT (e_address_widget_new_control ());
+ if (strcmp (component_id, COMPONENT_ID) == 0) {
+ BonoboObject *object = BONOBO_OBJECT (addressbook_component_peek ());
+ bonobo_object_ref (object);
+ return object;
+ }
if (strcmp (component_id, ADDRESS_POPUP_ID) == 0)
- return BONOBO_OBJECT (e_address_popup_new_control ());
+ return BONOBO_OBJECT (eab_popup_control_new ());
if (strcmp (component_id, LDAP_STORAGE_CONFIG_CONTROL_ID) == 0)
return BONOBO_OBJECT (addressbook_config_control_new ());
if (strcmp (component_id, SELECT_NAMES_ID) == 0)
diff --git a/addressbook/gui/component/e-address-popup.h b/addressbook/gui/component/e-address-popup.h
deleted file mode 100644
index b2519b0ee6..0000000000
--- a/addressbook/gui/component/e-address-popup.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-address-popup.h
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#ifndef __E_ADDRESS_POPUP_H__
-#define __E_ADDRESS_POPUP_H__
-
-#include <gtk/gtk.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <bonobo/bonobo-event-source.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_ADDRESS_POPUP (e_address_popup_get_type ())
-#define E_ADDRESS_POPUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESS_POPUP, EAddressPopup))
-#define E_ADDRESS_POPUP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_ADDRESS_POPUP, EAddressPopupClass))
-#define E_IS_ADDRESS_POPUP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESS_POPUP))
-#define E_IS_ADDRESS_POPUP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESS_POPUP))
-
-typedef struct _EAddressPopup EAddressPopup;
-typedef struct _EAddressPopupClass EAddressPopupClass;
-
-struct _EAddressPopup {
- GtkEventBox parent;
-
- gchar *name;
- gchar *email;
-
- GtkWidget *name_widget;
- GtkWidget *email_widget;
- GtkWidget *query_msg;
-
- GtkWidget *main_vbox;
- GtkWidget *generic_view;
- GtkWidget *minicard_view;
-
- gboolean transitory;
-
- guint scheduled_refresh;
- EBook *book;
- guint query_tag;
- gboolean multiple_matches;
- ECard *card;
-
- BonoboEventSource *es;
-};
-
-struct _EAddressPopupClass {
- GtkEventBoxClass parent_class;
-};
-
-GType e_address_popup_get_type (void);
-
-void e_address_popup_set_name (EAddressPopup *, const gchar *name);
-void e_address_popup_set_email (EAddressPopup *, const gchar *email);
-
-void e_address_popup_construct (EAddressPopup *);
-GtkWidget *e_address_popup_new (void);
-
-BonoboControl *e_address_popup_new_control (void);
-
-G_END_DECLS
-
-#endif /* __E_ADDRESS_POPUP_H__ */
-
diff --git a/addressbook/gui/component/e-address-widget.c b/addressbook/gui/component/e-address-widget.c
deleted file mode 100644
index 9ec1e6ebba..0000000000
--- a/addressbook/gui/component/e-address-widget.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-address-widget.c
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#include <config.h>
-#include <ctype.h>
-#include <string.h>
-#include <gtk/gtklabel.h>
-#include <libgnomeui/gnome-popup-menu.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-property-bag.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <addressbook/gui/contact-editor/e-contact-quick-add.h>
-#include "e-address-widget.h"
-
-static void e_address_widget_class_init (EAddressWidgetClass *klass);
-static void e_address_widget_init (EAddressWidget *obj);
-static void e_address_widget_destroy (GtkObject *obj);
-
-static gint e_address_widget_button_press_handler (GtkWidget *w, GdkEventButton *ev);
-static void e_address_widget_popup (EAddressWidget *, GdkEventButton *ev);
-static void e_address_widget_schedule_query (EAddressWidget *);
-
-static GtkObjectClass *parent_class;
-
-static EBook *common_book = NULL; /* sort of lame */
-
-static gboolean doing_queries = FALSE;
-
-static void
-e_address_widget_class_init (EAddressWidgetClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->destroy = e_address_widget_destroy;
-
- widget_class->button_press_event = e_address_widget_button_press_handler;
-}
-
-static void
-e_address_widget_init (EAddressWidget *addr)
-{
-
-}
-
-static void
-e_address_widget_destroy (GtkObject *obj)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (obj);
-
- g_free (addr->name);
- addr->name = NULL;
-
- g_free (addr->email);
- addr->email = NULL;
-
- if (addr->query_tag) {
- e_book_simple_query_cancel (common_book, addr->query_tag);
- addr->query_tag = 0;
- }
-
- if (addr->query_idle_tag) {
- g_source_remove (addr->query_idle_tag);
- addr->query_idle_tag = 0;
- }
-
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (obj);
-}
-
-static gint
-e_address_widget_button_press_handler (GtkWidget *w, GdkEventButton *ev)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (w);
- if (ev->button == 3 && ev->state == 0) {
- e_address_widget_popup (addr, ev);
- return TRUE;
- }
-
- return FALSE;
-}
-
-GType
-e_address_widget_get_type (void)
-{
- static GType aw_type = 0;
-
- if (!aw_type) {
- static const GTypeInfo aw_info = {
- sizeof (EAddressWidgetClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_address_widget_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EAddressWidget),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_address_widget_init,
- };
-
- aw_type = g_type_register_static (gtk_event_box_get_type (), "EAddressWidget", &aw_info, 0);
- }
-
- return aw_type;
-}
-
-static void
-gtk_widget_visible (GtkWidget *w, gboolean x)
-{
- if (x)
- gtk_widget_show (w);
- else
- gtk_widget_hide (w);
-}
-
-static void
-e_address_widget_refresh (EAddressWidget *addr)
-{
- gchar *str;
- gboolean have_name, have_email;
-
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- have_name = addr->name && *addr->name;
- have_email = addr->email && *addr->email && (addr->card == NULL || !addr->known_email);
-
- gtk_label_set_text (GTK_LABEL (addr->name_widget), have_name ? addr->name : "");
- gtk_widget_visible (addr->name_widget, have_name);
- if (addr->card) {
- gint i, N = strlen (addr->name);
- gchar *pattern = g_malloc (N+1);
- for (i=0; i<N; ++i)
- pattern[i] = '_';
- pattern[i] = '\0';
- gtk_label_set_pattern (GTK_LABEL (addr->name_widget), pattern);
- g_free (pattern);
- } else {
- gtk_label_set_pattern (GTK_LABEL (addr->name_widget), "");
- }
-
- if (have_email) {
- str = g_strdup_printf (have_name ? "<%s>" : "%s", addr->email);
- gtk_label_set_text (GTK_LABEL (addr->email_widget), str);
- g_free (str);
- } else {
- gtk_label_set_text (GTK_LABEL (addr->email_widget), "");
- }
- gtk_widget_visible (addr->email_widget, have_email);
-
- gtk_widget_visible (addr->spacer, have_name && have_email);
-
- /* Launch a query to find the appropriate card, if necessary. */
- if (addr->card == NULL)
- e_address_widget_schedule_query (addr);
-}
-
-void
-e_address_widget_set_name (EAddressWidget *addr, const gchar *name)
-{
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- g_free (addr->name);
- addr->name = g_strdup (name);
-
- e_address_widget_refresh (addr);
-}
-
-void
-e_address_widget_set_email (EAddressWidget *addr, const gchar *email)
-{
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- g_free (addr->email);
- addr->email = g_strdup (email);
-
- e_address_widget_refresh (addr);
-}
-
-
-void
-e_address_widget_set_text (EAddressWidget *addr, const gchar *text)
-{
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- e_address_widget_set_email (addr, text); /* CRAP */
-}
-
-void
-e_address_widget_construct (EAddressWidget *addr)
-{
- GtkWidget *box;
-
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- box = gtk_hbox_new (FALSE, 2);
-
- addr->name_widget = gtk_label_new ("");
- addr->spacer = gtk_label_new (" ");
- addr->email_widget = gtk_label_new ("");
-
- gtk_box_pack_start (GTK_BOX (box), addr->name_widget, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (box), addr->spacer, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (box), addr->email_widget, FALSE, FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (addr), box);
-
- gtk_widget_show (box);
- gtk_widget_show (addr->name_widget);
- gtk_widget_show (addr->email_widget);
-}
-
-GtkWidget *
-e_address_widget_new (void)
-{
- EAddressWidget *addr = g_object_new (E_TYPE_ADDRESS_WIDGET, NULL);
- e_address_widget_construct (addr);
- return GTK_WIDGET (addr);
-}
-
-/*
- *
- * Cardification
- *
- */
-
-static void
-e_address_widget_cardify (EAddressWidget *addr, ECard *card, gboolean known_email)
-{
- if (addr->card != card || addr->known_email != known_email) {
-
- if (addr->card != card) {
- if (addr->card)
- g_object_unref (addr->card);
- addr->card = card;
- g_object_ref (addr->card);
- }
-
- addr->known_email = known_email;
-
- if (!(addr->name && *addr->name)) {
- gchar *s = e_card_name_to_string (card->name);
- e_address_widget_set_name (addr, s);
- g_free (s);
- }
-
- e_address_widget_refresh (addr);
- }
-}
-
-static void
-query_results_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer user_data)
-{
- EAddressWidget *addr = user_data;
-
- if (g_list_length ((GList *) cards) == 1) {
- ECard *card = E_CARD (cards->data);
- e_address_widget_cardify (addr, card, TRUE);
- }
-
- addr->query_tag = 0;
-}
-
-static void
-e_address_widget_do_query (EAddressWidget *addr)
-{
- e_book_name_and_email_query (common_book, addr->name, addr->email, query_results_cb, addr);
-}
-
-static void
-book_ready_cb (EBook *book, EBookStatus status, gpointer user_data)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
-
- if (common_book == NULL) {
- common_book = book;
- g_object_ref (common_book);
- } else
- g_object_unref (book);
-
- e_address_widget_do_query (addr);
-}
-
-static gint
-query_idle_fn (gpointer ptr)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (ptr);
-
- if (common_book) {
- e_address_widget_do_query (addr);
- } else {
- e_book_load_default_book (e_book_new (), book_ready_cb, addr);
- }
-
- addr->query_idle_tag = 0;
- return FALSE;
-}
-
-static void
-e_address_widget_schedule_query (EAddressWidget *addr)
-{
- if (addr->query_idle_tag || !doing_queries)
- return;
- addr->query_idle_tag = g_idle_add (query_idle_fn, addr);
-}
-
-/*
- *
- * Popup Menu
- *
- */
-
-#define ARBITRARY_UIINFO_LIMIT 64
-
-static gint
-popup_add_name_and_address (EAddressWidget *addr, GnomeUIInfo *uiinfo, gint i)
-{
- gboolean flag = FALSE;
-
- if (addr->name && *addr->name) {
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = addr->name;
- ++i;
- flag = TRUE;
- }
-
- if (addr->email && *addr->email) {
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = addr->email;
- ++i;
- flag = TRUE;
- }
-
- if (flag) {
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
- }
-
- return i;
-}
-
-static void
-flip_queries_flag_cb (GtkWidget *w, gpointer user_data)
-{
- doing_queries = !doing_queries;
-}
-
-static gint
-popup_add_query_change (EAddressWidget *addr, GnomeUIInfo *uiinfo, gint i)
-{
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = doing_queries ? _("Disable Queries") : _("Enable Queries (Dangerous!)");
- uiinfo[i].moreinfo = flip_queries_flag_cb;
- ++i;
-
- return i;
-}
-
-
-static GtkWidget *
-popup_menu_card (EAddressWidget *addr)
-{
- GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
- GtkWidget *pop;
- gint i=0;
- ECard *card = E_CARD (addr->card);
-
- g_return_val_if_fail (card != NULL, NULL);
-
- memset (uiinfo, 0, sizeof (uiinfo));
-
- i = popup_add_name_and_address (addr, uiinfo, i);
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = _("Edit Contact Info");
- ++i;
-
- i = popup_add_query_change (addr, uiinfo, i);
-
- uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
- pop = gnome_popup_menu_new (uiinfo);
- return pop;
-}
-
-static void
-post_quick_add_cb (ECard *card, gpointer user_data)
-{
- e_address_widget_cardify (E_ADDRESS_WIDGET (user_data), card, TRUE);
-}
-
-static void
-add_contacts_cb (GtkWidget *w, gpointer user_data)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
-
- e_contact_quick_add (addr->name, addr->email, post_quick_add_cb, addr);
-}
-
-static GtkWidget *
-popup_menu_nocard (EAddressWidget *addr)
-{
- GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
- GtkWidget *pop;
- gint i=0;
-
- memset (uiinfo, 0, sizeof (uiinfo));
-
- i = popup_add_name_and_address (addr, uiinfo, i);
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = _("Add to Contacts");
- uiinfo[i].moreinfo = add_contacts_cb;
- ++i;
-
- i = popup_add_query_change (addr, uiinfo, i);
-
- uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
- pop = gnome_popup_menu_new (uiinfo);
- return pop;
-}
-
-static void
-e_address_widget_popup (EAddressWidget *addr, GdkEventButton *ev)
-{
- GtkWidget *pop;
-
- g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
-
- pop = addr->card ? popup_menu_card (addr) : popup_menu_nocard (addr);
-
- if (pop)
- gnome_popup_menu_do_popup (pop, NULL, NULL, ev, addr, GTK_WIDGET (addr));
-}
-
-/*
- *
- * Bonobo Control Magic
- *
- */
-
-enum {
- ADDRESS_PROPERTY_NAME,
- ADDRESS_PROPERTY_EMAIL,
- ADDRESS_PROPERTY_TEXT,
- ADDRESS_PROPERTY_BACKGROUND_RGB
-};
-
-
-static void
-get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
-
- switch (arg_id) {
-
- case ADDRESS_PROPERTY_NAME:
- BONOBO_ARG_SET_STRING (arg, addr->name ? addr->name :"");
- break;
-
- case ADDRESS_PROPERTY_EMAIL:
- BONOBO_ARG_SET_STRING (arg, addr->email ? addr->email : "");
- break;
-
- case ADDRESS_PROPERTY_TEXT:
- BONOBO_ARG_SET_STRING (arg, "?");
- break;
- }
-}
-
-static void
-set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
-{
- EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
-
- switch (arg_id) {
- case ADDRESS_PROPERTY_NAME:
- e_address_widget_set_name (addr, BONOBO_ARG_GET_STRING (arg));
- break;
-
- case ADDRESS_PROPERTY_EMAIL:
- e_address_widget_set_email (addr, BONOBO_ARG_GET_STRING (arg));
- break;
-
- case ADDRESS_PROPERTY_TEXT:
- e_address_widget_set_text (addr, BONOBO_ARG_GET_STRING (arg));
- break;
-
-
- case ADDRESS_PROPERTY_BACKGROUND_RGB:
- {
- gint bg = BONOBO_ARG_GET_INT (arg);
- GdkColor color;
-
- color.red = (bg & 0xff0000) >> 8;
- color.green = (bg & 0x00ff00);
- color.blue = (bg & 0x0000ff) << 8;
-
- if (gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (addr)), &color, FALSE, TRUE)) {
- GtkStyle *style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (addr)));
- style->bg[0] = color;
- gtk_widget_set_style (GTK_WIDGET (addr), style);
- }
- }
-
- break;
- }
-}
-
-BonoboControl *
-e_address_widget_factory_new_control (void)
-{
- BonoboControl *control;
- BonoboPropertyBag *bag;
- GtkWidget *w;
-
- w = e_address_widget_new ();
- gtk_widget_show (w);
-
- control = bonobo_control_new (w);
-
- bag = bonobo_property_bag_new (get_prop, set_prop, w);
- bonobo_property_bag_add (bag, "name", ADDRESS_PROPERTY_NAME,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
-
- bonobo_property_bag_add (bag, "email", ADDRESS_PROPERTY_EMAIL,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
-
- bonobo_property_bag_add (bag, "text", ADDRESS_PROPERTY_TEXT,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
-
- bonobo_property_bag_add (bag, "background_rgb", ADDRESS_PROPERTY_BACKGROUND_RGB,
- BONOBO_ARG_INT, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE);
-
- bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (bag)), NULL);
- bonobo_object_unref (BONOBO_OBJECT (bag));
-
- return control;
-}
diff --git a/addressbook/gui/component/e-address-widget.h b/addressbook/gui/component/e-address-widget.h
deleted file mode 100644
index 13e4a417d0..0000000000
--- a/addressbook/gui/component/e-address-widget.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-address-widget.h
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Developed by Jon Trowbridge <trow@ximian.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- */
-
-#ifndef __E_ADDRESS_WIDGET_H__
-#define __E_ADDRESS_WIDGET_H__
-
-#include <gtk/gtkeventbox.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkobject.h>
-#include <gtk/gtkwidget.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_ADDRESS_WIDGET (e_address_widget_get_type ())
-#define E_ADDRESS_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESS_WIDGET, EAddressWidget))
-#define E_ADDRESS_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_ADDRESS_WIDGET, EAddressWidgetClass))
-#define E_IS_ADDRESS_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESS_WIDGET))
-#define E_IS_ADDRESS_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESS_WIDGET))
-
-typedef struct _EAddressWidget EAddressWidget;
-typedef struct _EAddressWidgetClass EAddressWidgetClass;
-
-struct _EAddressWidget {
- GtkEventBox parent;
-
- gchar *name;
- gchar *email;
-
- GtkWidget *name_widget;
- GtkWidget *email_widget;
- GtkWidget *spacer;
-
- guint query_idle_tag;
- guint query_tag;
-
- ECard *card;
- gboolean known_email;
-};
-
-struct _EAddressWidgetClass {
- GtkEventBoxClass parent_class;
-};
-
-GType e_address_widget_get_type (void);
-
-void e_address_widget_set_name (EAddressWidget *, const gchar *name);
-void e_address_widget_set_email (EAddressWidget *, const gchar *email);
-void e_address_widget_set_text (EAddressWidget *, const gchar *text);
-
-void e_address_widget_construct (EAddressWidget *);
-GtkWidget *e_address_widget_new (void);
-
-BonoboControl *e_address_widget_new_control (void);
-
-G_END_DECLS
-
-#endif /* __E_ADDRESS_WIDGET_H__ */
diff --git a/addressbook/gui/component/e-cardlist-model.c b/addressbook/gui/component/e-cardlist-model.c
deleted file mode 100644
index be1ff3ddd2..0000000000
--- a/addressbook/gui/component/e-cardlist-model.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com>
- *
- * (C) 1999 Ximian, Inc.
- */
-
-#include <config.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-
-#include <string.h>
-
-#include "e-cardlist-model.h"
-
-#define PARENT_TYPE e_table_model_get_type()
-
-static GObjectClass *parent_class = NULL;
-
-static void
-e_cardlist_model_dispose(GObject *object)
-{
- ECardlistModel *model = E_CARDLIST_MODEL(object);
- int i;
-
- if (model->data != NULL) {
- for ( i = 0; i < model->data_count; i++ ) {
- g_object_unref(model->data[i]);
- }
- g_free(model->data);
- model->data = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-/* This function returns the number of columns in our ETableModel. */
-static int
-e_cardlist_model_col_count (ETableModel *etc)
-{
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-/* This function returns the number of rows in our ETableModel. */
-static int
-e_cardlist_model_row_count (ETableModel *etc)
-{
- ECardlistModel *e_cardlist_model = E_CARDLIST_MODEL(etc);
- return e_cardlist_model->data_count;
-}
-
-/* This function returns the value at a particular point in our ETableModel. */
-static void *
-e_cardlist_model_value_at (ETableModel *etc, int col, int row)
-{
- ECardlistModel *e_cardlist_model = E_CARDLIST_MODEL(etc);
- const char *value;
- if ( col >= E_CARD_SIMPLE_FIELD_LAST - 1|| row >= e_cardlist_model->data_count )
- return NULL;
- value = e_card_simple_get_const(e_cardlist_model->data[row],
- col + 1);
- return (void *)(value ? value : "");
-}
-
-/* This function sets the value at a particular point in our ETableModel. */
-static void
-e_cardlist_model_set_value_at (ETableModel *etc, int col, int row, const void *val)
-{
- ECardlistModel *e_cardlist_model = E_CARDLIST_MODEL(etc);
-
- if ( col >= E_CARD_SIMPLE_FIELD_LAST - 1|| row >= e_cardlist_model->data_count )
- return;
- e_table_model_pre_change(etc);
- e_card_simple_set(e_cardlist_model->data[row],
- col + 1,
- val);
-
- e_table_model_cell_changed(etc, col, row);
-}
-
-/* This function returns whether a particular cell is editable. */
-static gboolean
-e_cardlist_model_is_cell_editable (ETableModel *etc, int col, int row)
-{
- return TRUE;
-}
-
-/* This function duplicates the value passed to it. */
-static void *
-e_cardlist_model_duplicate_value (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
-
-/* This function frees the value passed to it. */
-static void
-e_cardlist_model_free_value (ETableModel *etc, int col, void *value)
-{
- g_free(value);
-}
-
-static void *
-e_cardlist_model_initialize_value (ETableModel *etc, int col)
-{
- return g_strdup("");
-}
-
-static gboolean
-e_cardlist_model_value_is_empty (ETableModel *etc, int col, const void *value)
-{
- return !(value && *(char *)value);
-}
-
-static char *
-e_cardlist_model_value_to_string (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
-
-void
-e_cardlist_model_add(ECardlistModel *model,
- ECard **cards,
- int count)
-{
- int i;
- model->data = g_realloc(model->data, model->data_count + count * sizeof(ECard *));
- for (i = 0; i < count; i++) {
- gboolean found = FALSE;
- const gchar *id = e_card_get_id(cards[i]);
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_simple_get_id(model->data[i]), id) ) {
- found = TRUE;
- break;
- }
- }
- if (!found) {
- e_table_model_pre_change(E_TABLE_MODEL(model));
- g_object_ref(cards[i]);
- model->data[model->data_count++] = e_card_simple_new (cards[i]);
- e_table_model_row_inserted(E_TABLE_MODEL(model), model->data_count - 1);
- }
- }
-}
-
-void
-e_cardlist_model_remove(ECardlistModel *model,
- const char *id)
-{
- int i;
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_simple_get_id(model->data[i]), id) ) {
- e_table_model_pre_change(E_TABLE_MODEL(model));
- g_object_unref(model->data[i]);
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
- e_table_model_row_deleted(E_TABLE_MODEL(model), i);
- }
- }
-}
-
-static void
-e_cardlist_model_class_init (GObjectClass *object_class)
-{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- parent_class = g_type_class_peek_parent (object_class);
-
- object_class->dispose = e_cardlist_model_dispose;
-
- model_class->column_count = e_cardlist_model_col_count;
- model_class->row_count = e_cardlist_model_row_count;
- model_class->value_at = e_cardlist_model_value_at;
- model_class->set_value_at = e_cardlist_model_set_value_at;
- model_class->is_cell_editable = e_cardlist_model_is_cell_editable;
- model_class->duplicate_value = e_cardlist_model_duplicate_value;
- model_class->free_value = e_cardlist_model_free_value;
- model_class->initialize_value = e_cardlist_model_initialize_value;
- model_class->value_is_empty = e_cardlist_model_value_is_empty;
- model_class->value_to_string = e_cardlist_model_value_to_string;
-}
-
-static void
-e_cardlist_model_init (GObject *object)
-{
- ECardlistModel *model = E_CARDLIST_MODEL(object);
- model->data = NULL;
- model->data_count = 0;
-}
-
-ECard *
-e_cardlist_model_get(ECardlistModel *model,
- int row)
-{
- if (model->data && row < model->data_count) {
- ECard *card;
- g_object_get(model->data[row],
- "card", &card,
- NULL);
- return card;
- }
- return NULL;
-}
-
-GType
-e_cardlist_model_get_type (void)
-{
- static GType aw_type = 0;
-
- if (!aw_type) {
- static const GTypeInfo aw_info = {
- sizeof (ECardlistModelClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_cardlist_model_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ECardlistModel),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_cardlist_model_init,
- };
-
- aw_type = g_type_register_static (PARENT_TYPE, "ECardlistModel", &aw_info, 0);
- }
-
- return aw_type;
-}
-
-ETableModel *
-e_cardlist_model_new (void)
-{
- ECardlistModel *et;
-
- et = g_object_new (E_TYPE_CARDLIST_MODEL, NULL);
-
- return E_TABLE_MODEL(et);
-}
diff --git a/addressbook/gui/component/e-cardlist-model.h b/addressbook/gui/component/e-cardlist-model.h
deleted file mode 100644
index 0968e936fc..0000000000
--- a/addressbook/gui/component/e-cardlist-model.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_CARDLIST_MODEL_H_
-#define _E_CARDLIST_MODEL_H_
-
-#include <gal/e-table/e-table-model.h>
-#include <ebook/e-book.h>
-#include <ebook/e-book-view.h>
-#include <ebook/e-card-simple.h>
-
-#define E_TYPE_CARDLIST_MODEL (e_cardlist_model_get_type ())
-#define E_CARDLIST_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_CARDLIST_MODEL, ECardlistModel))
-#define E_CARDLIST_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_CARDLIST_MODEL, ECardlistModelClass))
-#define E_IS_CARDLIST_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_CARDLIST_MODEL))
-#define E_IS_CARDLIST_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_CARDLIST_MODEL))
-
-typedef struct {
- ETableModel parent;
-
- /* item specific fields */
- ECardSimple **data;
- int data_count;
-} ECardlistModel;
-
-
-typedef struct {
- ETableModelClass parent_class;
-} ECardlistModelClass;
-
-
-GType e_cardlist_model_get_type (void);
-ETableModel *e_cardlist_model_new (void);
-
-/* Returns object with an extra ref count. */
-ECard *e_cardlist_model_get (ECardlistModel *model,
- int row);
-void e_cardlist_model_add (ECardlistModel *model,
- ECard **card,
- int count);
-void e_cardlist_model_remove (ECardlistModel *model,
- const char *id);
-
-#endif /* _E_CARDLIST_MODEL_H_ */
diff --git a/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl b/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
index 2959597cc5..6feb6b54bb 100644
--- a/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
+++ b/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
@@ -14,78 +14,6 @@ module GNOME {
module Evolution {
module Addressbook {
- interface SimpleCard : Bonobo::Unknown {
- struct Arbitrary {
- string key;
- string type;
- string value;
- };
-
- enum Field {
- FileAs,
- FullName,
- Email,
- PhonePrimary,
- PhoneAssistant,
- PhoneBusiness,
- PhoneCallback,
- PhoneCompany,
- PhoneHome,
- Org,
- AddressBusiness,
- AddressHome,
- PhoneMobile,
- PhoneCar,
- PhoneBusinessFax,
- PhoneHomeFax,
- PhoneBusiness2,
- PhoneHome2,
- PhoneIsdn,
- PhoneOther,
- PhoneOtherFax,
- PhonePager,
- PhoneRadio,
- PhoneTelex,
- PhoneTtytdd,
- AddressOther,
- Email2,
- Email3,
- Url,
- OrgUnit,
- Office,
- Title,
- Role,
- Manager,
- Assistant,
- Nickname,
- Spouse,
- Note,
- Caluri,
- Fburl,
- Icscalendar,
- Anniversary,
- BirthDate,
- Mailer,
- NameOrOrg,
- Categories,
- FamilyName,
- GivenName,
- AdditionalName,
- NameSuffix,
- WantsHtml,
- IsList,
- Last
- };
-
- Arbitrary getArbitrary (in string key);
- void setArbitrary (in string key, in string type, in string value);
-
- string get (in Field field);
- void set (in Field field, in string value);
- };
-
- typedef sequence<SimpleCard> SimpleCardList;
-
interface SelectNames : Bonobo::Unknown {
struct Section {
string id;
diff --git a/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in b/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in
index 6e4d156051..80b138f1dc 100644
--- a/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in
+++ b/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.server.in.in
@@ -17,7 +17,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_SelectNames"
type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory">
+ location="OAFIID:GNOME_Evolution_Addressbook_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/Addressbook/SelectNames"/>
@@ -28,4 +28,4 @@
</oaf_server>
-</oaf_info> \ No newline at end of file
+</oaf_info>
diff --git a/addressbook/gui/component/select-names/Makefile.am b/addressbook/gui/component/select-names/Makefile.am
index 051a168815..b78e5b69fe 100644
--- a/addressbook/gui/component/select-names/Makefile.am
+++ b/addressbook/gui/component/select-names/Makefile.am
@@ -69,9 +69,7 @@ libeselectnames_la_SOURCES = \
e-select-names-text-model.c \
e-select-names-text-model.h \
e-select-names.c \
- e-select-names.h \
- e-simple-card-bonobo.c \
- e-simple-card-bonobo.h
+ e-select-names.h
libeselectnames_la_LIBADD = \
$(top_builddir)/addressbook/backend/ebook/libebook.la \
diff --git a/addressbook/gui/component/select-names/e-select-names-bonobo.c b/addressbook/gui/component/select-names/e-select-names-bonobo.c
index 10fc9caee7..f10fa3b804 100644
--- a/addressbook/gui/component/select-names/e-select-names-bonobo.c
+++ b/addressbook/gui/component/select-names/e-select-names-bonobo.c
@@ -25,7 +25,6 @@
#endif
#include "e-select-names-bonobo.h"
-#include "e-simple-card-bonobo.h"
#include <bonobo-activation/bonobo-activation-activate.h>
@@ -63,7 +62,6 @@ enum _EntryPropertyID {
ENTRY_PROPERTY_ID_TEXT,
ENTRY_PROPERTY_ID_ADDRESSES,
ENTRY_PROPERTY_ID_DESTINATIONS,
- ENTRY_PROPERTY_ID_SIMPLE_CARD_LIST,
ENTRY_PROPERTY_ID_ALLOW_CONTACT_LISTS,
ENTRY_PROPERTY_ID_ENTRY_CHANGED
};
@@ -122,38 +120,6 @@ entry_get_property_fn (BonoboPropertyBag *bag,
}
break;
- case ENTRY_PROPERTY_ID_SIMPLE_CARD_LIST:
- {
- ESelectNamesModel *model;
- int count;
- int i;
- GNOME_Evolution_Addressbook_SimpleCardList *card_list;
-
- model = E_SELECT_NAMES_MODEL (g_object_get_data (G_OBJECT (w), "select_names_model"));
- g_assert (model != NULL);
-
- count = e_select_names_model_count (model);
-
- card_list = GNOME_Evolution_Addressbook_SimpleCardList__alloc ();
- card_list->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_SimpleCard_allocbuf (count);
- card_list->_maximum = count;
- card_list->_length = count;
-
- for (i = 0; i < count; i++) {
- const EDestination *destination = e_select_names_model_get_destination (model, i);
- const ECard *card = e_destination_get_card (destination);
- ECardSimple *simple = e_card_simple_new ((ECard *) card);
- ESimpleCardBonobo *simple_card = e_simple_card_bonobo_new (simple);
- g_object_unref (simple);
-
- card_list->_buffer[i] = bonobo_object_corba_objref (BONOBO_OBJECT (simple_card));
- }
-
- CORBA_free (*(GNOME_Evolution_Addressbook_SimpleCardList **)arg->_value);
- BONOBO_ARG_SET_GENERAL (arg, *card_list, TC_GNOME_Evolution_Addressbook_SimpleCardList, GNOME_Evolution_Addressbook_SimpleCardList, NULL);
- }
- break;
-
case ENTRY_PROPERTY_ID_ALLOW_CONTACT_LISTS:
{
ESelectNamesCompletion *comp;
@@ -195,7 +161,7 @@ entry_set_property_fn (BonoboPropertyBag *bag,
g_assert (model != NULL);
e_entry_set_text (E_ENTRY (w), BONOBO_ARG_GET_STRING (arg));
- e_select_names_model_cardify_all (model, NULL, 0);
+ e_select_names_model_load_all_contacts (model, NULL);
break;
}
@@ -206,7 +172,7 @@ entry_set_property_fn (BonoboPropertyBag *bag,
g_assert (model != NULL);
e_select_names_model_import_destinationv (model, BONOBO_ARG_GET_STRING (arg));
- e_select_names_model_cardify_all (model, NULL, 0);
+ e_select_names_model_load_all_contacts (model, NULL);
break;
}
@@ -499,9 +465,6 @@ impl_SelectNames_get_entry_for_section (PortableServer_Servant servant,
bonobo_property_bag_add (property_bag, "destinations", ENTRY_PROPERTY_ID_DESTINATIONS,
BONOBO_ARG_STRING, NULL, NULL,
BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
- bonobo_property_bag_add (property_bag, "simple_card_list", ENTRY_PROPERTY_ID_SIMPLE_CARD_LIST,
- TC_GNOME_Evolution_Addressbook_SimpleCardList, NULL, NULL,
- BONOBO_PROPERTY_READABLE);
bonobo_property_bag_add (property_bag, "allow_contact_lists", ENTRY_PROPERTY_ID_ALLOW_CONTACT_LISTS,
BONOBO_ARG_BOOLEAN, NULL, NULL,
BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
diff --git a/addressbook/gui/component/select-names/e-select-names-completion.c b/addressbook/gui/component/select-names/e-select-names-completion.c
index 5a9fc2deb4..7bfbfd2a5a 100644
--- a/addressbook/gui/component/select-names/e-select-names-completion.c
+++ b/addressbook/gui/component/select-names/e-select-names-completion.c
@@ -34,17 +34,17 @@
#include <gtk/gtksignal.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-destination.h>
-#include <addressbook/backend/ebook/e-card-simple.h>
-#include <addressbook/backend/ebook/e-card-compare.h>
+#include <addressbook/util/eab-book-util.h>
+#include <addressbook/util/eab-destination.h>
+#include <addressbook/gui/merging/eab-contact-compare.h>
+#include <addressbook/backend/ebook/e-contact.h>
typedef struct {
EBook *book;
guint book_view_tag;
EBookView *book_view;
ESelectNamesCompletion *comp;
- guint card_added_tag;
+ guint contacts_added_tag;
guint seq_complete_tag;
gboolean sequence_complete_received;
@@ -76,7 +76,7 @@ static void e_select_names_completion_init (ESelectNamesCompletion *);
static void e_select_names_completion_dispose (GObject *object);
static void e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBookView *view, gpointer user_data);
-static void e_select_names_completion_card_added_cb (EBookView *, const GList *cards, gpointer user_data);
+static void e_select_names_completion_contacts_added_cb (EBookView *, const GList *cards, gpointer user_data);
static void e_select_names_completion_seq_complete_cb (EBookView *, EBookViewStatus status, gpointer user_data);
static void e_select_names_completion_do_query (ESelectNamesCompletion *, const gchar *query_text, gint pos, gint limit);
@@ -95,7 +95,7 @@ static FILE *out;
*/
typedef gchar *(*BookQuerySExp) (ESelectNamesCompletion *);
-typedef ECompletionMatch *(*BookQueryMatchTester) (ESelectNamesCompletion *, EDestination *);
+typedef ECompletionMatch *(*BookQueryMatchTester) (ESelectNamesCompletion *, EABDestination *);
static int
utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len)
@@ -125,14 +125,16 @@ our_match_destroy (ECompletionMatch *match)
}
static ECompletionMatch *
-make_match (EDestination *dest, const gchar *menu_form, double score)
+make_match (EABDestination *dest, const gchar *menu_form, double score)
{
ECompletionMatch *match;
- ECard *card = e_destination_get_card (dest);
+#if notyet
+ EContact *contact = eab_destination_get_contact (dest);
+#endif
- match = e_completion_match_new (e_destination_get_name (dest), menu_form, score);
+ match = e_completion_match_new (eab_destination_get_name (dest), menu_form, score);
- e_completion_match_set_text (match, e_destination_get_name (dest), menu_form);
+ e_completion_match_set_text (match, eab_destination_get_name (dest), menu_form);
/* Reject any match that has null text fields. */
if (! (e_completion_match_get_match_text (match) && e_completion_match_get_menu_text (match))) {
@@ -140,10 +142,15 @@ make_match (EDestination *dest, const gchar *menu_form, double score)
return NULL;
}
+#if notyet
+ /* XXX toshok - EContact doesn't have the use_score stuff */
/* Since we sort low to high, we negate so that larger use scores will come first */
- match->sort_major = card ? -floor (e_card_get_use_score (card)) : 0;
+ match->sort_major = contact ? -floor (e_contact_get_use_score (contact)) : 0;
+#else
+ match->sort_major = 0;
+#endif
- match->sort_minor = e_destination_get_email_num (dest);
+ match->sort_minor = eab_destination_get_email_num (dest);
match->user_data = dest;
g_object_ref (dest);
@@ -166,31 +173,33 @@ sexp_nickname (ESelectNamesCompletion *comp)
}
static ECompletionMatch *
-match_nickname (ESelectNamesCompletion *comp, EDestination *dest)
+match_nickname (ESelectNamesCompletion *comp, EABDestination *dest)
{
ECompletionMatch *match = NULL;
gint len;
- ECard *card = e_destination_get_card (dest);
+ EContact *contact = eab_destination_get_contact (dest);
double score;
+ const char *nickname;
- if (card->nickname == NULL)
+ nickname = e_contact_get_const (contact, E_CONTACT_NICKNAME);
+ if (nickname == NULL)
return NULL;
len = g_utf8_strlen (comp->priv->query_text, -1);
- if (card->nickname && !utf8_casefold_collate_len (comp->priv->query_text, card->nickname, len)) {
+ if (nickname && !utf8_casefold_collate_len (comp->priv->query_text, nickname, len)) {
const gchar *name;
gchar *str;
score = len * 2; /* nickname gives 2 points per matching character */
- if (len == g_utf8_strlen (card->nickname, -1)) /* boost score on an exact match */
+ if (len == g_utf8_strlen (nickname, -1)) /* boost score on an exact match */
score *= 10;
- name = e_destination_get_name (dest);
+ name = eab_destination_get_name (dest);
if (name && *name)
- str = g_strdup_printf ("'%s' %s <%s>", card->nickname, name, e_destination_get_email (dest));
+ str = g_strdup_printf ("'%s' %s <%s>", nickname, name, eab_destination_get_email (dest));
else
- str = g_strdup_printf ("'%s' <%s>", card->nickname, e_destination_get_email (dest));
+ str = g_strdup_printf ("'%s' <%s>", nickname, eab_destination_get_email (dest));
match = make_match (dest, str, score);
g_free (str);
@@ -210,17 +219,17 @@ sexp_email (ESelectNamesCompletion *comp)
}
static ECompletionMatch *
-match_email (ESelectNamesCompletion *comp, EDestination *dest)
+match_email (ESelectNamesCompletion *comp, EABDestination *dest)
{
ECompletionMatch *match;
gint len = strlen (comp->priv->query_text);
- const gchar *name = e_destination_get_name (dest);
- const gchar *email = e_destination_get_email (dest);
+ const gchar *name = eab_destination_get_name (dest);
+ const gchar *email = eab_destination_get_email (dest);
double score;
if (email
&& !utf8_casefold_collate_len (comp->priv->query_text, email, len)
- && !e_destination_is_evolution_list (dest)) {
+ && !eab_destination_is_evolution_list (dest)) {
gchar *str;
@@ -294,78 +303,82 @@ sexp_name (ESelectNamesCompletion *comp)
}
static ECompletionMatch *
-match_name (ESelectNamesCompletion *comp, EDestination *dest)
+match_name (ESelectNamesCompletion *comp, EABDestination *dest)
{
ECompletionMatch *final_match = NULL;
gchar *menu_text = NULL;
- ECard *card;
+ EContact *contact;
const gchar *email;
gint match_len = 0;
- ECardMatchType match;
- ECardMatchPart first_match;
+ EABContactMatchType match;
+ EABContactMatchPart first_match;
double score = 0;
gboolean have_given, have_additional, have_family;
+ EContactName *contact_name;
- card = e_destination_get_card (dest);
-
- if (card->name == NULL)
+ contact = eab_destination_get_contact (dest);
+
+ contact_name = e_contact_get (contact, E_CONTACT_NAME);
+ if (!contact_name)
return NULL;
- email = e_destination_get_email (dest);
+ email = eab_destination_get_email (dest);
- match = e_card_compare_name_to_string_full (card, comp->priv->query_text, TRUE /* yes, allow partial matches */,
- NULL, &first_match, &match_len);
+ match = eab_contact_compare_name_to_string_full (contact, comp->priv->query_text, TRUE /* yes, allow partial matches */,
+ NULL, &first_match, &match_len);
- if (match <= E_CARD_MATCH_NONE)
+ if (match <= EAB_CONTACT_MATCH_NONE) {
+ e_contact_name_free (contact_name);
return NULL;
+ }
score = match_len * 3; /* three points per match character */
- have_given = card->name->given && *card->name->given;
- have_additional = card->name->additional && *card->name->additional;
- have_family = card->name->family && *card->name->family;
+ have_given = contact_name->given && *contact_name->given;
+ have_additional = contact_name->additional && *contact_name->additional;
+ have_family = contact_name->family && *contact_name->family;
- if (e_card_evolution_list (card)) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
- menu_text = e_card_name_to_string (card->name);
+ menu_text = e_contact_name_to_string (contact_name);
- } else if (first_match == E_CARD_MATCH_PART_GIVEN_NAME) {
+ } else if (first_match == EAB_CONTACT_MATCH_PART_GIVEN_NAME) {
if (have_family)
- menu_text = g_strdup_printf ("%s %s <%s>", card->name->given, card->name->family, email);
+ menu_text = g_strdup_printf ("%s %s <%s>", contact_name->given, contact_name->family, email);
else
- menu_text = g_strdup_printf ("%s <%s>", card->name->given, email);
+ menu_text = g_strdup_printf ("%s <%s>", contact_name->given, email);
- } else if (first_match == E_CARD_MATCH_PART_ADDITIONAL_NAME) {
+ } else if (first_match == EAB_CONTACT_MATCH_PART_ADDITIONAL_NAME) {
if (have_given) {
menu_text = g_strdup_printf ("%s%s%s, %s <%s>",
- card->name->additional,
+ contact_name->additional,
have_family ? " " : "",
- have_family ? card->name->family : "",
- card->name->given,
+ have_family ? contact_name->family : "",
+ contact_name->given,
email);
} else {
menu_text = g_strdup_printf ("%s%s%s <%s>",
- card->name->additional,
+ contact_name->additional,
have_family ? " " : "",
- have_family ? card->name->family : "",
+ have_family ? contact_name->family : "",
email);
}
- } else if (first_match == E_CARD_MATCH_PART_FAMILY_NAME) {
+ } else if (first_match == EAB_CONTACT_MATCH_PART_FAMILY_NAME) {
if (have_given)
menu_text = g_strdup_printf ("%s, %s%s%s <%s>",
- card->name->family,
- card->name->given,
+ contact_name->family,
+ contact_name->given,
have_additional ? " " : "",
- have_additional ? card->name->additional : "",
+ have_additional ? contact_name->additional : "",
email);
else
- menu_text = g_strdup_printf ("%s <%s>", card->name->family, email);
+ menu_text = g_strdup_printf ("%s <%s>", contact_name->family, email);
} else { /* something funny happened */
@@ -379,6 +392,8 @@ match_name (ESelectNamesCompletion *comp, EDestination *dest)
g_free (menu_text);
}
+ e_contact_name_free (contact_name);
+
return final_match;
}
@@ -393,7 +408,7 @@ sexp_file_as (ESelectNamesCompletion *comp)
}
static ECompletionMatch *
-match_file_as (ESelectNamesCompletion *comp, EDestination *dest)
+match_file_as (ESelectNamesCompletion *comp, EABDestination *dest)
{
const gchar *name;
const gchar *email;
@@ -402,8 +417,8 @@ match_file_as (ESelectNamesCompletion *comp, EDestination *dest)
double score = 0.00001;
ECompletionMatch *match;
- name = e_destination_get_name (dest);
- email = e_destination_get_email (dest);
+ name = eab_destination_get_name (dest);
+ email = eab_destination_get_email (dest);
if (!(name && *name))
return NULL;
@@ -491,13 +506,13 @@ book_query_sexp (ESelectNamesCompletion *comp)
* string that applies to a given destination.
*/
static ECompletionMatch *
-book_query_score (ESelectNamesCompletion *comp, EDestination *dest)
+book_query_score (ESelectNamesCompletion *comp, EABDestination *dest)
{
ECompletionMatch *best_match = NULL;
gint i;
g_return_val_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp), NULL);
- g_return_val_if_fail (E_IS_DESTINATION (dest), NULL);
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), NULL);
if (! (comp->priv->query_text && *comp->priv->query_text))
return NULL;
@@ -506,7 +521,7 @@ book_query_score (ESelectNamesCompletion *comp, EDestination *dest)
ECompletionMatch *this_match = NULL;
- if (book_queries[i].tester && e_destination_get_card (dest)) {
+ if (book_queries[i].tester && eab_destination_get_contact (dest)) {
this_match = book_queries[i].tester (comp, dest);
}
@@ -524,18 +539,18 @@ book_query_score (ESelectNamesCompletion *comp, EDestination *dest)
}
static void
-book_query_process_card_list (ESelectNamesCompletion *comp, const GList *cards)
+book_query_process_card_list (ESelectNamesCompletion *comp, const GList *contacts)
{
- while (cards) {
- ECard *card = E_CARD (cards->data);
+ while (contacts) {
+ EContact *contact = E_CONTACT (contacts->data);
- if (e_card_evolution_list (card)) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
if (comp->priv->match_contact_lists) {
- EDestination *dest = e_destination_new ();
+ EABDestination *dest = eab_destination_new ();
ECompletionMatch *match;
- e_destination_set_card (dest, card, 0);
+ eab_destination_set_contact (dest, contact, 0);
match = book_query_score (comp, dest);
if (match && match->score > 0) {
e_completion_found_match (E_COMPLETION (comp), match);
@@ -546,31 +561,38 @@ book_query_process_card_list (ESelectNamesCompletion *comp, const GList *cards)
}
- } else if (card->email) {
- gint i;
- for (i=0; i<e_list_length (card->email); ++i) {
- EDestination *dest = e_destination_new ();
- const gchar *email;
- ECompletionMatch *match;
+ }
+ else {
+ GList *email = e_contact_get (contact, E_CONTACT_EMAIL);
+ if (email) {
+ GList *iter;
+ gint i;
+ for (i=0, iter = email; iter; ++i, iter = iter->next) {
+ EABDestination *dest = eab_destination_new ();
+ gchar *e;
+ ECompletionMatch *match;
- e_destination_set_card (dest, card, i);
- email = e_destination_get_email (dest);
+ eab_destination_set_contact (dest, contact, i);
+ e = iter->data;
- if (email && *email) {
+ if (e && *e) {
- match = book_query_score (comp, dest);
- if (match && match->score > 0) {
- e_completion_found_match (E_COMPLETION (comp), match);
- } else {
- e_completion_match_unref (match);
+ match = book_query_score (comp, dest);
+ if (match && match->score > 0) {
+ e_completion_found_match (E_COMPLETION (comp), match);
+ } else {
+ e_completion_match_unref (match);
+ }
}
- }
- g_object_unref (dest);
+ g_object_unref (dest);
+ }
}
+ g_list_foreach (email, (GFunc)g_free, NULL);
+ g_list_free (email);
}
- cards = g_list_next (cards);
+ contacts = contacts->next;
}
}
@@ -640,9 +662,9 @@ e_select_names_completion_clear_book_data (ESelectNamesCompletion *comp)
for (l = comp->priv->book_data; l; l = l->next) {
ESelectNamesCompletionBookData *book_data = l->data;
- if (book_data->card_added_tag) {
- g_signal_handler_disconnect (book_data->book_view, book_data->card_added_tag);
- book_data->card_added_tag = 0;
+ if (book_data->contacts_added_tag) {
+ g_signal_handler_disconnect (book_data->book_view, book_data->contacts_added_tag);
+ book_data->contacts_added_tag = 0;
}
if (book_data->seq_complete_tag) {
@@ -756,7 +778,7 @@ e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBo
book_data = (ESelectNamesCompletionBookData*)user_data;
comp = book_data->comp;
- if (status != E_BOOK_STATUS_SUCCESS) {
+ if (status != E_BOOK_ERROR_OK) {
comp->priv->pending_completion_seq--;
if (!comp->priv->pending_completion_seq)
e_select_names_completion_done (comp);
@@ -765,9 +787,9 @@ e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBo
book_data->book_view_tag = 0;
- if (book_data->card_added_tag) {
- g_signal_handler_disconnect (book_data->book_view, book_data->card_added_tag);
- book_data->card_added_tag = 0;
+ if (book_data->contacts_added_tag) {
+ g_signal_handler_disconnect (book_data->book_view, book_data->contacts_added_tag);
+ book_data->contacts_added_tag = 0;
}
if (book_data->seq_complete_tag) {
g_signal_handler_disconnect (book_data->book_view, book_data->seq_complete_tag);
@@ -781,10 +803,10 @@ e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBo
}
book_data->book_view = view;
- book_data->card_added_tag =
+ book_data->contacts_added_tag =
g_signal_connect (view,
- "card_added",
- G_CALLBACK (e_select_names_completion_card_added_cb),
+ "contacts_added",
+ G_CALLBACK (e_select_names_completion_contacts_added_cb),
book_data);
book_data->seq_complete_tag =
@@ -792,11 +814,14 @@ e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBo
"sequence_complete",
G_CALLBACK (e_select_names_completion_seq_complete_cb),
book_data);
+
+ e_book_view_start (view);
+
book_data->sequence_complete_received = FALSE;
}
static void
-e_select_names_completion_card_added_cb (EBookView *book_view, const GList *cards, gpointer user_data)
+e_select_names_completion_contacts_added_cb (EBookView *book_view, const GList *cards, gpointer user_data)
{
ESelectNamesCompletionBookData *book_data = user_data;
ESelectNamesCompletion *comp = book_data->comp;
@@ -834,7 +859,7 @@ e_select_names_completion_seq_complete_cb (EBookView *book_view, EBookViewStatus
}
if (book_data->cached_query_text
- && status == E_BOOK_STATUS_SUCCESS
+ && status == E_BOOK_ERROR_OK
&& !book_data->cache_complete
&& !strcmp (book_data->cached_query_text, comp->priv->query_text))
book_data->cache_complete = TRUE;
@@ -845,9 +870,9 @@ e_select_names_completion_seq_complete_cb (EBookView *book_view, EBookViewStatus
if (!book_data->sequence_complete_received) {
book_data->sequence_complete_received = TRUE;
- if (book_data->card_added_tag) {
- g_signal_handler_disconnect (book_data->book_view, book_data->card_added_tag);
- book_data->card_added_tag = 0;
+ if (book_data->contacts_added_tag) {
+ g_signal_handler_disconnect (book_data->book_view, book_data->contacts_added_tag);
+ book_data->contacts_added_tag = 0;
}
if (book_data->seq_complete_tag) {
g_signal_handler_disconnect (book_data->book_view, book_data->seq_complete_tag);
@@ -888,13 +913,15 @@ e_select_names_completion_stop_query (ESelectNamesCompletion *comp)
for (l = comp->priv->book_data; l; l = l->next) {
ESelectNamesCompletionBookData *book_data = l->data;
if (book_data->book_view_tag) {
+#if notyet
e_book_cancel (book_data->book, book_data->book_view_tag);
+#endif
book_data->book_view_tag = 0;
}
if (book_data->book_view) {
- if (book_data->card_added_tag) {
- g_signal_handler_disconnect (book_data->book_view, book_data->card_added_tag);
- book_data->card_added_tag = 0;
+ if (book_data->contacts_added_tag) {
+ g_signal_handler_disconnect (book_data->book_view, book_data->contacts_added_tag);
+ book_data->contacts_added_tag = 0;
}
if (book_data->seq_complete_tag) {
g_signal_handler_disconnect (book_data->book_view, book_data->seq_complete_tag);
@@ -977,13 +1004,10 @@ e_select_names_completion_start_query (ESelectNamesCompletion *comp, const gchar
e_select_names_completion_clear_cache (book_data);
book_data->cached_query_text = g_strdup (query_text);
- book_data->book_view_tag = e_book_get_completion_view (book_data->book,
+ book_data->book_view_tag = e_book_async_get_book_view (book_data->book,
sexp,
e_select_names_completion_got_book_view_cb, book_data);
- if (! book_data->book_view_tag)
- g_warning ("Exception calling e_book_get_completion_view");
- else
- comp->priv->pending_completion_seq++;
+ comp->priv->pending_completion_seq++;
}
if (out)
diff --git a/addressbook/gui/component/select-names/e-select-names-completion.h b/addressbook/gui/component/select-names/e-select-names-completion.h
index 6565208378..435fe80041 100644
--- a/addressbook/gui/component/select-names/e-select-names-completion.h
+++ b/addressbook/gui/component/select-names/e-select-names-completion.h
@@ -28,7 +28,7 @@
#define E_SELECT_NAMES_COMPLETION_H
#include <gal/e-text/e-completion.h>
-#include <addressbook/backend/ebook/e-book.h>
+#include <addressbook/backend/ebook/e-book-async.h>
#include "e-select-names-text-model.h"
G_BEGIN_DECLS
diff --git a/addressbook/gui/component/select-names/e-select-names-manager.c b/addressbook/gui/component/select-names/e-select-names-manager.c
index a3875cea97..e095f7308f 100644
--- a/addressbook/gui/component/select-names/e-select-names-manager.c
+++ b/addressbook/gui/component/select-names/e-select-names-manager.c
@@ -24,8 +24,8 @@
#include "e-select-names-completion.h"
#include "e-select-names-popup.h"
#include "e-folder-list.h"
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-destination.h>
+#include <addressbook/util/eab-book-util.h>
+#include <addressbook/util/eab-destination.h>
#include "addressbook/gui/component/addressbook.h"
#include <bonobo/bonobo-object.h>
@@ -175,7 +175,7 @@ focus_in_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
entry->cleaning_tag = 0;
}
- e_select_names_model_cancel_cardify_all (entry->model);
+ e_select_names_model_cancel_all_contact_load (entry->model);
return FALSE;
}
@@ -189,7 +189,7 @@ focus_out_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
gboolean visible = e_entry_completion_popup_is_visible (entry->entry);
if (! visible) {
- e_select_names_model_cardify_all (entry->model, entry->manager->completion_book, 100);
+ e_select_names_model_load_all_contacts (entry->model, entry->manager->completion_book, 100);
if (entry->cleaning_tag == 0)
entry->cleaning_tag = gtk_timeout_add (100, clean_cb, entry);
}
@@ -205,7 +205,7 @@ completion_popup_cb (EEntry *w, gint visible, gpointer user_data)
ESelectNamesManagerEntry *entry = user_data;
if (!visible && !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (entry->entry->canvas)))
- e_select_names_model_cardify_all (entry->model, entry->manager->completion_book, 0);
+ e_select_names_model_load_all_contacts (entry->model, entry->manager->completion_book, 0);
#endif
}
@@ -214,14 +214,14 @@ completion_handler (EEntry *entry, ECompletionMatch *match)
{
ESelectNamesManagerEntry *mgr_entry;
ESelectNamesTextModel *text_model;
- EDestination *dest;
+ EABDestination *dest;
gint i, pos, start_pos, len;
if (match == NULL || match->user_data == NULL)
return;
mgr_entry = get_entry_info (entry);
- dest = E_DESTINATION (match->user_data);
+ dest = EAB_DESTINATION (match->user_data);
/* Sometimes I really long for garbage collection. Reference
counting makes you feel 31337, but sometimes it is just a
@@ -377,7 +377,7 @@ e_select_names_manager_discard_saved_models (ESelectNamesManager *manager)
static void
open_book_cb (EBook *book, EBookStatus status, ESelectNamesManager *manager)
{
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
GList *l;
for (l = manager->entries; l; l = l->next) {
ESelectNamesManagerEntry *entry = l->data;
@@ -398,15 +398,10 @@ load_completion_books (ESelectNamesManager *manager)
EFolderListItem *f;
for (f = folders; f && f->physical_uri; f++) {
- char *uri;
EBook *book = e_book_new ();
g_object_ref (manager); /* ref ourself before our async call */
- uri = e_book_expand_uri (f->physical_uri);
-
- addressbook_load_uri (book, uri, (EBookCallback)open_book_cb, manager);
-
- g_free (uri);
+ addressbook_load_uri (book, f->physical_uri, (EBookCallback)open_book_cb, manager);
}
e_folder_list_free_items (folders);
}
@@ -485,7 +480,7 @@ e_select_names_manager_new (void)
ESelectNamesManager *manager = g_object_new (E_TYPE_SELECT_NAMES_MANAGER, NULL);
EConfigListener *db;
- db = e_book_get_config_database();
+ db = eab_get_config_database();
manager->listener_id = g_signal_connect (db,
"key_changed",
@@ -685,7 +680,7 @@ e_select_names_manager_dispose (GObject *object)
}
if (manager->listener_id) {
- g_signal_handler_disconnect (e_book_get_config_database(), manager->listener_id);
+ g_signal_handler_disconnect (eab_get_config_database(), manager->listener_id);
manager->listener_id = 0;
}
diff --git a/addressbook/gui/component/select-names/e-select-names-model.c b/addressbook/gui/component/select-names/e-select-names-model.c
index 6c3cb0f9c6..d95aebde5d 100644
--- a/addressbook/gui/component/select-names/e-select-names-model.c
+++ b/addressbook/gui/component/select-names/e-select-names-model.c
@@ -19,7 +19,7 @@
#include "e-select-names-model.h"
#include "e-select-names-marshal.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include "addressbook/backend/ebook/e-contact.h"
#define MAX_LENGTH 2047
@@ -35,14 +35,14 @@ static guint e_select_names_model_signals[E_SELECT_NAMES_MODEL_LAST_SIGNAL] = {
/* Object argument IDs */
enum {
ARG_0,
- ARG_CARD,
+ ARG_CONTACT,
};
struct _ESelectNamesModelPrivate {
gchar *id;
gchar *title;
- GList *data; /* of EDestination */
+ GList *data; /* of EABDestination */
gint limit;
@@ -159,7 +159,7 @@ e_select_names_model_changed (ESelectNamesModel *model)
}
static void
-destination_changed_proxy (EDestination *dest, gpointer closure)
+destination_changed_proxy (EABDestination *dest, gpointer closure)
{
e_select_names_model_changed (E_SELECT_NAMES_MODEL (closure));
}
@@ -184,7 +184,7 @@ e_select_names_model_duplicate (ESelectNamesModel *old)
model->priv->title = g_strdup (old->priv->title);
for (iter = old->priv->data; iter != NULL; iter = g_list_next (iter)) {
- EDestination *dup = e_destination_copy (E_DESTINATION (iter->data));
+ EABDestination *dup = eab_destination_copy (EAB_DESTINATION (iter->data));
e_select_names_model_append (model, dup);
}
@@ -212,8 +212,8 @@ e_select_names_model_get_textification (ESelectNamesModel *model, const char *se
GList *iter = model->priv->data;
while (iter) {
- EDestination *dest = E_DESTINATION (iter->data);
- strv[i] = (gchar *) e_destination_get_textrep (dest, FALSE);
+ EABDestination *dest = EAB_DESTINATION (iter->data);
+ strv[i] = (gchar *) eab_destination_get_textrep (dest, FALSE);
++i;
iter = g_list_next (iter);
}
@@ -252,8 +252,8 @@ e_select_names_model_get_address_text (ESelectNamesModel *model, const char *sep
GList *iter = model->priv->data;
while (iter) {
- EDestination *dest = E_DESTINATION (iter->data);
- strv[i] = (gchar *) e_destination_get_address (dest);
+ EABDestination *dest = EAB_DESTINATION (iter->data);
+ strv[i] = (gchar *) eab_destination_get_address (dest);
if (strv[i])
++i;
iter = g_list_next (iter);
@@ -304,43 +304,42 @@ e_select_names_model_at_limit (ESelectNamesModel *model)
return model->priv->limit >= 0 && g_list_length (model->priv->data) >= model->priv->limit;
}
-const EDestination *
+const EABDestination *
e_select_names_model_get_destination (ESelectNamesModel *model, gint index)
{
g_return_val_if_fail (model && E_IS_SELECT_NAMES_MODEL (model), NULL);
g_return_val_if_fail (0 <= index, NULL);
g_return_val_if_fail (index < g_list_length (model->priv->data), NULL);
- return E_DESTINATION (g_list_nth_data (model->priv->data, index));
+ return EAB_DESTINATION (g_list_nth_data (model->priv->data, index));
}
gchar *
e_select_names_model_export_destinationv (ESelectNamesModel *model)
{
- EDestination **destv;
+ EABDestination **destv;
gchar *str;
gint i, len = 0;
GList *j;
g_return_val_if_fail (model && E_IS_SELECT_NAMES_MODEL (model), NULL);
len = g_list_length (model->priv->data);
- destv = g_new0 (EDestination *, len+1);
+ destv = g_new0 (EABDestination *, len+1);
for (i=0, j = model->priv->data; j != NULL; j = g_list_next (j)) {
- EDestination *dest = E_DESTINATION (j->data);
+ EABDestination *dest = EAB_DESTINATION (j->data);
if (dest)
destv[i++] = dest;
}
- str = e_destination_exportv (destv);
+ str = eab_destination_exportv (destv);
g_free (destv);
return str;
}
-static
-void send_changed (EDestination *dest, ECard *card, gpointer closure)
+static void send_changed (EABDestination *dest, EContact *contact, gpointer closure)
{
ESelectNamesModel *model = closure;
e_select_names_model_changed (model);
@@ -350,12 +349,12 @@ void
e_select_names_model_import_destinationv (ESelectNamesModel *model,
gchar *destinationv)
{
- EDestination **destv;
+ EABDestination **destv;
gint i;
g_return_if_fail (model && E_IS_SELECT_NAMES_MODEL (model));
- destv = e_destination_importv (destinationv);
+ destv = eab_destination_importv (destinationv);
e_select_names_model_delete_all (model);
@@ -363,30 +362,30 @@ e_select_names_model_import_destinationv (ESelectNamesModel *model,
return;
for (i = 0; destv[i]; i++) {
- e_destination_use_card (destv[i], send_changed, model);
+ eab_destination_use_contact (destv[i], send_changed, model);
e_select_names_model_append (model, destv[i]);
}
g_free (destv);
}
-ECard *
-e_select_names_model_get_card (ESelectNamesModel *model, gint index)
+EContact *
+e_select_names_model_get_contact (ESelectNamesModel *model, gint index)
{
- const EDestination *dest;
+ const EABDestination *dest;
g_return_val_if_fail (model && E_IS_SELECT_NAMES_MODEL (model), NULL);
g_return_val_if_fail (0 <= index, NULL);
g_return_val_if_fail (index < g_list_length (model->priv->data), NULL);
dest = e_select_names_model_get_destination (model, index);
- return dest ? e_destination_get_card (dest) : NULL;
+ return dest ? eab_destination_get_contact (dest) : NULL;
}
const gchar *
e_select_names_model_get_string (ESelectNamesModel *model, gint index)
{
- const EDestination *dest;
+ const EABDestination *dest;
g_return_val_if_fail (model && E_IS_SELECT_NAMES_MODEL (model), NULL);
g_return_val_if_fail (0 <= index, NULL);
@@ -394,11 +393,11 @@ e_select_names_model_get_string (ESelectNamesModel *model, gint index)
dest = e_select_names_model_get_destination (model, index);
- return dest ? e_destination_get_textrep (dest, FALSE) : "";
+ return dest ? eab_destination_get_textrep (dest, FALSE) : "";
}
static void
-connect_destination (ESelectNamesModel *model, EDestination *dest)
+connect_destination (ESelectNamesModel *model, EABDestination *dest)
{
g_signal_connect (dest,
"changed",
@@ -407,21 +406,21 @@ connect_destination (ESelectNamesModel *model, EDestination *dest)
}
static void
-disconnect_destination (ESelectNamesModel *model, EDestination *dest)
+disconnect_destination (ESelectNamesModel *model, EABDestination *dest)
{
g_signal_handlers_disconnect_by_func (dest, destination_changed_proxy, model);
}
gboolean
-e_select_names_model_contains (ESelectNamesModel *model, const EDestination *dest)
+e_select_names_model_contains (ESelectNamesModel *model, const EABDestination *dest)
{
GList *iter;
g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), FALSE);
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), FALSE);
for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
- if (iter->data != NULL && e_destination_equal (dest, E_DESTINATION (iter->data)))
+ if (iter->data != NULL && eab_destination_equal (dest, EAB_DESTINATION (iter->data)))
return TRUE;
}
@@ -429,12 +428,12 @@ e_select_names_model_contains (ESelectNamesModel *model, const EDestination *des
}
void
-e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination *dest)
+e_select_names_model_insert (ESelectNamesModel *model, gint index, EABDestination *dest)
{
g_return_if_fail (model != NULL);
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
g_return_if_fail (0 <= index && index <= g_list_length (model->priv->data));
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
if (e_select_names_model_at_limit (model)) {
/* FIXME: This is bad. */
@@ -452,10 +451,10 @@ e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination
}
void
-e_select_names_model_append (ESelectNamesModel *model, EDestination *dest)
+e_select_names_model_append (ESelectNamesModel *model, EABDestination *dest)
{
g_return_if_fail (model && E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
if (e_select_names_model_at_limit (model)) {
/* FIXME: This is bad. */
@@ -473,7 +472,7 @@ e_select_names_model_append (ESelectNamesModel *model, EDestination *dest)
}
void
-e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination *dest)
+e_select_names_model_replace (ESelectNamesModel *model, gint index, EABDestination *dest)
{
GList *node;
const gchar *new_str, *old_str;
@@ -482,9 +481,9 @@ e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination
g_return_if_fail (model != NULL);
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
g_return_if_fail (model->priv->data == NULL || (0 <= index && index < g_list_length (model->priv->data)));
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
- new_str = e_destination_get_textrep (dest, FALSE);
+ new_str = eab_destination_get_textrep (dest, FALSE);
new_strlen = new_str ? strlen (new_str) : 0;
if (model->priv->data == NULL) {
@@ -500,10 +499,10 @@ e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination
if (node->data != dest) {
- disconnect_destination (model, E_DESTINATION (node->data));
+ disconnect_destination (model, EAB_DESTINATION (node->data));
connect_destination (model, dest);
- old_str = e_destination_get_textrep (E_DESTINATION (node->data), FALSE);
+ old_str = eab_destination_get_textrep (EAB_DESTINATION (node->data), FALSE);
old_strlen = old_str ? strlen (old_str) : 0;
g_object_unref (node->data);
@@ -523,14 +522,14 @@ void
e_select_names_model_delete (ESelectNamesModel *model, gint index)
{
GList *node;
- EDestination *dest;
+ EABDestination *dest;
g_return_if_fail (model != NULL);
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
node = g_list_nth (model->priv->data, index);
- dest = E_DESTINATION (node->data);
+ dest = EAB_DESTINATION (node->data);
disconnect_destination (model, dest);
g_object_unref (dest);
@@ -552,16 +551,16 @@ e_select_names_model_clean (ESelectNamesModel *model, gboolean clean_last_entry)
iter = model->priv->data;
while (iter) {
- EDestination *dest;
+ EABDestination *dest;
next = g_list_next (iter);
if (next == NULL && !clean_last_entry)
break;
- dest = iter->data ? E_DESTINATION (iter->data) : NULL;
+ dest = iter->data ? EAB_DESTINATION (iter->data) : NULL;
- if (dest == NULL || e_destination_is_empty (dest)) {
+ if (dest == NULL || eab_destination_is_empty (dest)) {
if (dest) {
disconnect_destination (model, dest);
g_object_unref (dest);
@@ -581,7 +580,7 @@ e_select_names_model_clean (ESelectNamesModel *model, gboolean clean_last_entry)
static void
delete_all_iter (gpointer data, gpointer closure)
{
- disconnect_destination (E_SELECT_NAMES_MODEL (closure), E_DESTINATION (data));
+ disconnect_destination (E_SELECT_NAMES_MODEL (closure), EAB_DESTINATION (data));
g_object_unref (data);
}
@@ -611,9 +610,9 @@ e_select_names_model_overwrite_copy (ESelectNamesModel *dest, ESelectNamesModel
e_select_names_model_delete_all (dest);
len = e_select_names_model_count (src);
for (i = 0; i < len; ++i) {
- const EDestination *d = e_select_names_model_get_destination (src, i);
+ const EABDestination *d = e_select_names_model_get_destination (src, i);
if (d)
- e_select_names_model_append (dest, e_destination_copy (d));
+ e_select_names_model_append (dest, eab_destination_copy (d));
}
}
@@ -630,9 +629,9 @@ e_select_names_model_merge (ESelectNamesModel *dest, ESelectNamesModel *src)
len = e_select_names_model_count (src);
for (i = 0; i < len; ++i) {
- const EDestination *d = e_select_names_model_get_destination (src, i);
+ const EABDestination *d = e_select_names_model_get_destination (src, i);
if (d && !e_select_names_model_contains (dest, d))
- e_select_names_model_append (dest, e_destination_copy (d));
+ e_select_names_model_append (dest, eab_destination_copy (d));
}
}
@@ -650,7 +649,7 @@ e_select_names_model_name_pos (ESelectNamesModel *model, gint seplen, gint index
iter = model->priv->data;
while (iter && i <= index) {
rp += len + (i > 0 ? seplen : 0);
- str = e_destination_get_textrep (E_DESTINATION (iter->data), FALSE);
+ str = eab_destination_get_textrep (EAB_DESTINATION (iter->data), FALSE);
len = str ? g_utf8_strlen (str, -1) : 0;
++i;
iter = g_list_next (iter);
@@ -680,7 +679,7 @@ e_select_names_model_text_pos (ESelectNamesModel *model, gint seplen, gint pos,
iter = model->priv->data;
while (iter != NULL) {
- str = e_destination_get_textrep (E_DESTINATION (iter->data), FALSE);
+ str = eab_destination_get_textrep (EAB_DESTINATION (iter->data), FALSE);
len = str ? g_utf8_strlen (str, -1) : 0;
if (sp <= pos && pos <= sp + len + adj) {
@@ -719,65 +718,7 @@ e_select_names_model_text_pos (ESelectNamesModel *model, gint seplen, gint pos,
}
void
-e_select_names_model_cardify (ESelectNamesModel *model, EBook *book, gint index, gint delay)
-{
- EDestination *dest;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (book == NULL || E_IS_BOOK (book));
- g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
-
- dest = E_DESTINATION (g_list_nth_data (model->priv->data, index));
-
- if (!e_destination_is_empty (dest)) {
-
- if (delay > 0)
- e_destination_cardify_delayed (dest, book, delay);
- else
- e_destination_cardify (dest, book);
- }
-}
-
-gboolean
-e_select_names_model_uncardify (ESelectNamesModel *model, gint index)
-{
- EDestination *dest;
- gboolean rv = FALSE;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), FALSE);
- g_return_val_if_fail (0 <= index && index < g_list_length (model->priv->data), FALSE);
-
- dest = E_DESTINATION (g_list_nth_data (model->priv->data, index));
-
- if (!e_destination_is_empty (dest)) {
- EDestination *cpy_dest = e_destination_copy (dest);
-
- rv = e_destination_uncardify (cpy_dest);
-
- if (rv) {
- e_select_names_model_replace (model, index, cpy_dest);
- }
-
- }
-
- return rv;
-}
-
-void
-e_select_names_model_cancel_cardify (ESelectNamesModel *model, gint index)
-{
- EDestination *dest;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
-
- dest = E_DESTINATION (g_list_nth_data (model->priv->data, index));
-
- e_destination_cancel_cardify (dest);
-}
-
-void
-e_select_names_model_cardify_all (ESelectNamesModel *model, EBook *book, gint delay)
+e_select_names_model_load_all_contacts (ESelectNamesModel *model, EBook *book)
{
GList *iter;
@@ -785,27 +726,27 @@ e_select_names_model_cardify_all (ESelectNamesModel *model, EBook *book, gint de
g_return_if_fail (book == NULL || E_IS_BOOK (book));
for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
- EDestination *dest = E_DESTINATION (iter->data);
- if (!e_destination_is_empty (dest)) {
+ EABDestination *dest = EAB_DESTINATION (iter->data);
+ if (!eab_destination_is_empty (dest)) {
- if (delay > 0)
- e_destination_cardify_delayed (dest, book, delay);
- else
- e_destination_cardify (dest, book);
+ eab_destination_load_contact (dest, book);
}
}
}
void
-e_select_names_model_cancel_cardify_all (ESelectNamesModel *model)
+e_select_names_model_cancel_all_contact_load (ESelectNamesModel *model)
{
GList *iter;
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
- EDestination *dest = E_DESTINATION (iter->data);
- e_destination_cancel_cardify (dest);
+ EABDestination *dest = EAB_DESTINATION (iter->data);
+ if (!eab_destination_is_empty (dest)) {
+
+ eab_destination_cancel_contact_load (dest);
+ }
}
}
diff --git a/addressbook/gui/component/select-names/e-select-names-model.h b/addressbook/gui/component/select-names/e-select-names-model.h
index 8a3c5381b7..41d5100f59 100644
--- a/addressbook/gui/component/select-names/e-select-names-model.h
+++ b/addressbook/gui/component/select-names/e-select-names-model.h
@@ -15,8 +15,8 @@
#include <gtk/gtkobject.h>
#include <stdio.h>
#include <e-util/e-list.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <addressbook/backend/ebook/e-destination.h>
+#include <addressbook/backend/ebook/e-contact.h>
+#include <addressbook/util/eab-destination.h>
#define E_TYPE_SELECT_NAMES_MODEL (e_select_names_model_get_type ())
#define E_SELECT_NAMES_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SELECT_NAMES_MODEL, ESelectNamesModel))
@@ -54,18 +54,18 @@ gint e_select_names_model_get_limit (ESelectNamesModel
void e_select_names_model_set_limit (ESelectNamesModel *model, gint limit);
gboolean e_select_names_model_at_limit (ESelectNamesModel *model);
-const EDestination *e_select_names_model_get_destination (ESelectNamesModel *model, gint index);
-gchar *e_select_names_model_export_destinationv (ESelectNamesModel *model);
-void e_select_names_model_import_destinationv (ESelectNamesModel *model,
+const EABDestination *e_select_names_model_get_destination (ESelectNamesModel *model, gint index);
+gchar *e_select_names_model_export_destinationv (ESelectNamesModel *model);
+void e_select_names_model_import_destinationv (ESelectNamesModel *model,
gchar *destinationv);
-ECard *e_select_names_model_get_card (ESelectNamesModel *model, gint index);
+EContact *e_select_names_model_get_contact (ESelectNamesModel *model, gint index);
const gchar *e_select_names_model_get_string (ESelectNamesModel *model, gint index);
-gboolean e_select_names_model_contains (ESelectNamesModel *model, const EDestination *dest);
+gboolean e_select_names_model_contains (ESelectNamesModel *model, const EABDestination *dest);
-void e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination *dest);
-void e_select_names_model_append (ESelectNamesModel *model, EDestination *dest);
-void e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination *dest);
+void e_select_names_model_insert (ESelectNamesModel *model, gint index, EABDestination *dest);
+void e_select_names_model_append (ESelectNamesModel *model, EABDestination *dest);
+void e_select_names_model_replace (ESelectNamesModel *model, gint index, EABDestination *dest);
void e_select_names_model_delete (ESelectNamesModel *model, gint index);
void e_select_names_model_delete_all (ESelectNamesModel *model);
void e_select_names_model_overwrite_copy (ESelectNamesModel *dest, ESelectNamesModel *src);
@@ -76,11 +76,8 @@ void e_select_names_model_clean (ESelectNamesModel *model, gboolea
void e_select_names_model_name_pos (ESelectNamesModel *model, gint seplen, gint index, gint *pos, gint *length);
void e_select_names_model_text_pos (ESelectNamesModel *model, gint seplen, gint pos, gint *index, gint *start_pos, gint *length);
-void e_select_names_model_cardify (ESelectNamesModel *model, EBook *book, gint index, gint delay);
-gboolean e_select_names_model_uncardify (ESelectNamesModel *model, gint index);
-void e_select_names_model_cancel_cardify (ESelectNamesModel *model, gint index);
-void e_select_names_model_cardify_all (ESelectNamesModel *model, EBook *book, gint delay);
-void e_select_names_model_cancel_cardify_all (ESelectNamesModel *model);
+void e_select_names_model_load_all_contacts (ESelectNamesModel *model, EBook *book);
+void e_select_names_model_cancel_all_contact_load (ESelectNamesModel *model);
/* This is a mildly annoying freeze/thaw pair, in that it only applies to the 'changed'
signal and not to 'resized'. This could cause unexpected results in some cases. */
diff --git a/addressbook/gui/component/select-names/e-select-names-popup.c b/addressbook/gui/component/select-names/e-select-names-popup.c
index d7fabd9426..bb0f331516 100644
--- a/addressbook/gui/component/select-names/e-select-names-popup.c
+++ b/addressbook/gui/component/select-names/e-select-names-popup.c
@@ -39,10 +39,11 @@
#include <gtk/gtklabel.h>
#include <libgnome/gnome-i18n.h>
-#include <addressbook/backend/ebook/e-book-util.h>
+#include <addressbook/util/eab-book-util.h>
#include <addressbook/gui/contact-editor/e-contact-editor.h>
+#include <addressbook/gui/contact-list-editor/e-contact-list-editor.h>
#include <addressbook/gui/contact-editor/e-contact-quick-add.h>
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
#include "e-select-names-popup.h"
#define LIST_ICON_FILENAME "contact-list-16.png"
@@ -51,13 +52,13 @@
typedef struct _PopupInfo PopupInfo;
struct _PopupInfo {
ESelectNamesTextModel *text_model;
- EDestination *dest;
+ EABDestination *dest;
gint pos;
gint index;
};
static PopupInfo *
-popup_info_new (ESelectNamesTextModel *text_model, EDestination *dest, gint pos, gint index)
+popup_info_new (ESelectNamesTextModel *text_model, EABDestination *dest, gint pos, gint index)
{
PopupInfo *info = g_new0 (PopupInfo, 1);
info->text_model = text_model;
@@ -97,29 +98,29 @@ popup_info_cleanup (GtkWidget *w, gpointer info)
/* You are in a maze of twisty little callbacks, all alike... */
+#if TOO_MANY_MENU_ITEMS
static void
make_contact_editor_cb (EBook *book, gpointer user_data)
{
if (book) {
- EDestination *dest = E_DESTINATION (user_data);
- ECard *card;
+ EABDestination *dest = EAB_DESTINATION (user_data);
+ EContact *contact;
- card = (ECard *) e_destination_get_card (dest);
- if (e_card_evolution_list (card)) {
+ contact = (EContact *) eab_destination_get_contact (dest);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
EContactListEditor *ce;
- ce = e_addressbook_show_contact_list_editor (book, card, FALSE, TRUE);
+ ce = e_addressbook_show_contact_list_editor (book, contact, FALSE, TRUE);
e_contact_list_editor_raise (ce);
}
else {
EContactEditor *ce;
- ce = e_addressbook_show_contact_editor (book, card, FALSE, TRUE);
+ ce = e_addressbook_show_contact_editor (book, contact, FALSE, TRUE);
e_contact_editor_raise (ce);
}
g_object_unref (dest);
}
}
-#if TOO_MANY_MENU_ITEMS
static void
edit_contact_info_cb (GtkWidget *w, gpointer user_data)
{
@@ -137,7 +138,7 @@ change_email_num_cb (GtkWidget *w, gpointer user_data)
{
PopupInfo *info = (PopupInfo *) user_data;
gint n;
- EDestination *dest;
+ EABDestination *dest;
if (info == NULL)
return;
@@ -147,9 +148,9 @@ change_email_num_cb (GtkWidget *w, gpointer user_data)
n = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "number"));
- if (n != e_destination_get_email_num (info->dest)) {
- dest = e_destination_new ();
- e_destination_set_card (dest, e_destination_get_card (info->dest), n);
+ if (n != eab_destination_get_email_num (info->dest)) {
+ dest = eab_destination_new ();
+ eab_destination_set_contact (dest, eab_destination_get_contact (info->dest), n);
e_select_names_model_replace (info->text_model->source, info->index, dest);
}
}
@@ -174,7 +175,7 @@ toggle_html_mail_cb (GtkWidget *w, gpointer user_data)
{
PopupInfo *info = (PopupInfo *) user_data;
GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (w);
- const EDestination *dest;
+ const EABDestination *dest;
if (info == NULL)
return;
@@ -182,19 +183,19 @@ toggle_html_mail_cb (GtkWidget *w, gpointer user_data)
dest = info->dest;
item = GTK_CHECK_MENU_ITEM (item);
- e_destination_set_html_mail_pref ((EDestination *) dest, item->active);
+ eab_destination_set_html_mail_pref ((EABDestination *) dest, item->active);
}
#endif
static void
-populate_popup_card (GtkWidget *pop, gboolean list, PopupInfo *info)
+populate_popup_contact (GtkWidget *pop, gboolean list, PopupInfo *info)
{
GtkWidget *image;
- ECard *card;
- EIterator *iterator;
+ EContact *contact;
GtkWidget *menuitem;
+ GList *email_list;
- card = e_destination_get_card (info->dest);
+ contact = eab_destination_get_contact (info->dest);
#if TOO_MANY_MENU_ITEMS
menuitem = gtk_separator_menu_item_new();
@@ -224,7 +225,7 @@ populate_popup_card (GtkWidget *pop, gboolean list, PopupInfo *info)
menuitem = gtk_check_menu_item_new_with_label (_("Send HTML Mail?"));
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
- e_destination_get_html_mail_pref (info->dest));
+ eab_destination_get_html_mail_pref (info->dest));
g_signal_connect (menuitem, "toggled",
G_CALLBACK (toggle_html_mail_cb),
info);
@@ -232,25 +233,27 @@ populate_popup_card (GtkWidget *pop, gboolean list, PopupInfo *info)
gtk_menu_shell_prepend (GTK_MENU_SHELL (pop), menuitem);
#endif
- if (card->email) {
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+
+ if (email_list) {
menuitem = gtk_separator_menu_item_new();
gtk_widget_show (menuitem);
gtk_menu_shell_prepend (GTK_MENU_SHELL (pop), menuitem);
- if (e_list_length (card->email) > 1) {
+ if (g_list_length (email_list) > 1) {
+ GList *l;
GSList *radiogroup = NULL;
- gint n = e_destination_get_email_num (info->dest);
- gint j = e_list_length (card->email) - 1;
+ gint n = eab_destination_get_email_num (info->dest);
+ gint j = g_list_length (email_list) - 1;
- iterator = e_list_get_iterator (card->email);
- for (e_iterator_last (iterator); e_iterator_is_valid (iterator); e_iterator_prev (iterator)) {
- char *email = (char *)e_iterator_get (iterator);
+ for (l = g_list_last (email_list); l; l = l->prev) {
+ char *email = l->data;
char *label = NULL;
if (!strncmp (email, "<?xml", 5)) {
- EDestination *dest = e_destination_import (email);
+ EABDestination *dest = eab_destination_import (email);
if (dest) {
- label = g_strdup (e_destination_get_textrep (dest, TRUE));
+ label = g_strdup (eab_destination_get_textrep (dest, TRUE));
g_object_unref (dest);
}
}
@@ -280,13 +283,14 @@ populate_popup_card (GtkWidget *pop, gboolean list, PopupInfo *info)
g_free (label);
}
-
- g_object_unref (iterator);
} else {
- menuitem = gtk_menu_item_new_with_label (e_destination_get_email (info->dest));
+ menuitem = gtk_menu_item_new_with_label (eab_destination_get_email (info->dest));
gtk_widget_show (menuitem);
gtk_menu_shell_prepend (GTK_MENU_SHELL (pop), menuitem);
}
+
+ g_list_foreach (email_list, (GFunc)g_free, NULL);
+ g_list_free (email_list);
}
menuitem = gtk_separator_menu_item_new ();
@@ -297,7 +301,7 @@ populate_popup_card (GtkWidget *pop, gboolean list, PopupInfo *info)
? EVOLUTION_IMAGESDIR "/" LIST_ICON_FILENAME
: EVOLUTION_IMAGESDIR "/" CONTACT_ICON_FILENAME);
gtk_widget_show (image);
- menuitem = gtk_image_menu_item_new_with_label (e_destination_get_name (info->dest));
+ menuitem = gtk_image_menu_item_new_with_label (eab_destination_get_name (info->dest));
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
image);
gtk_widget_show (menuitem);
@@ -308,11 +312,11 @@ static void
quick_add_cb (GtkWidget *w, gpointer user_data)
{
PopupInfo *info = (PopupInfo *) user_data;
- e_contact_quick_add_free_form (e_destination_get_address (info->dest), NULL, NULL);
+ e_contact_quick_add_free_form (eab_destination_get_address (info->dest), NULL, NULL);
}
static void
-populate_popup_nocard (GtkWidget *pop, PopupInfo *info)
+populate_popup_nocontact (GtkWidget *pop, PopupInfo *info)
{
const gchar *str;
GtkWidget *menuitem;
@@ -331,7 +335,7 @@ populate_popup_nocard (GtkWidget *pop, PopupInfo *info)
#if TOO_MANY_MENU_ITEMS
menuitem = gtk_check_menu_item_new_with_label (_("Send HTML Mail?"));
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
- e_destination_get_html_mail_pref (info->dest));
+ eab_destination_get_html_mail_pref (info->dest));
g_signal_connect (menuitem, "toggled",
G_CALLBACK (toggle_html_mail_cb),
info);
@@ -343,9 +347,9 @@ populate_popup_nocard (GtkWidget *pop, PopupInfo *info)
gtk_widget_show (menuitem);
gtk_menu_shell_prepend (GTK_MENU_SHELL (pop), menuitem);
- str = e_destination_get_name (info->dest);
+ str = eab_destination_get_name (info->dest);
if (! (str && *str))
- str = e_destination_get_email (info->dest);
+ str = eab_destination_get_email (info->dest);
if (! (str && *str))
str = _("Unnamed Contact");
@@ -360,7 +364,7 @@ e_select_names_populate_popup (GtkWidget *menu, ESelectNamesTextModel *text_mode
{
ESelectNamesModel *model;
PopupInfo *info;
- EDestination *dest;
+ EABDestination *dest;
gint index;
g_return_if_fail (GTK_IS_MENU_SHELL (menu));
@@ -375,16 +379,16 @@ e_select_names_populate_popup (GtkWidget *menu, ESelectNamesTextModel *text_mode
return;
/* XXX yuck, why does this return a const? */
- dest = (EDestination *)e_select_names_model_get_destination (model, index);
- if (e_destination_is_empty (dest))
+ dest = (EABDestination *)e_select_names_model_get_destination (model, index);
+ if (eab_destination_is_empty (dest))
return;
info = popup_info_new (text_model, dest, pos, index);
- if (e_destination_contains_card (dest)) {
- populate_popup_card (menu, e_destination_is_evolution_list (dest), info);
+ if (eab_destination_get_contact (dest)) {
+ populate_popup_contact (menu, eab_destination_is_evolution_list (dest), info);
} else {
- populate_popup_nocard (menu, info);
+ populate_popup_nocontact (menu, info);
}
/* Clean up our info item after we've made our selection. */
diff --git a/addressbook/gui/component/select-names/e-select-names-table-model.c b/addressbook/gui/component/select-names/e-select-names-table-model.c
index 1c55c3804d..14261e9d80 100644
--- a/addressbook/gui/component/select-names/e-select-names-table-model.c
+++ b/addressbook/gui/component/select-names/e-select-names-table-model.c
@@ -16,7 +16,7 @@
#include <libgnome/gnome-i18n.h>
#include "e-select-names-table-model.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include "addressbook/backend/ebook/e-contact.h"
/* Object argument IDs */
enum {
@@ -118,21 +118,19 @@ fill_in_info (ESelectNamesTableModel *model)
model->data = g_new(ESelectNamesTableModelData, count);
for (i = 0; i < count; ++i) {
- const EDestination *dest = e_select_names_model_get_destination (model->source, i);
- ECard *card = dest ? e_destination_get_card (dest) : NULL;
+ const EABDestination *dest = e_select_names_model_get_destination (model->source, i);
+ EContact *contact = dest ? eab_destination_get_contact (dest) : NULL;
- if (card) {
- ECardSimple *simple = e_card_simple_new(card);
- model->data[i].name = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_NAME_OR_ORG);
+ if (contact) {
+ model->data[i].name = e_contact_get(contact, E_CONTACT_FULL_NAME);
if (model->data[i].name == 0)
model->data[i].name = g_strdup("");
- model->data[i].email = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_EMAIL);
+ model->data[i].email = e_contact_get(contact, E_CONTACT_EMAIL_1);
if (model->data[i].email == 0)
model->data[i].email = g_strdup("");
- g_object_unref(simple);
} else {
- const gchar *name = e_destination_get_name (dest);
- const gchar *email = e_destination_get_email (dest);
+ const gchar *name = eab_destination_get_name (dest);
+ const gchar *email = eab_destination_get_email (dest);
model->data[i].name = g_strdup (name && *name ? name : email);
model->data[i].email = g_strdup (email);
diff --git a/addressbook/gui/component/select-names/e-select-names-text-model.c b/addressbook/gui/component/select-names/e-select-names-text-model.c
index 7859d5b056..e885de5bf6 100644
--- a/addressbook/gui/component/select-names/e-select-names-text-model.c
+++ b/addressbook/gui/component/select-names/e-select-names-text-model.c
@@ -19,7 +19,7 @@
#include <addressbook/gui/contact-editor/e-contact-editor.h>
#include "e-select-names-text-model.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
static FILE *out = NULL; /* stream for debugging spew */
@@ -137,7 +137,7 @@ dump_model (ESelectNamesTextModel *text_model)
for (i=0; i<e_select_names_model_count (model); ++i)
fprintf (out, "[%d] \"%s\" %s\n", i,
e_select_names_model_get_string (model, i),
- e_select_names_model_get_card (model, i) ? "<card>" : "");
+ e_select_names_model_get_contact (model, i) ? "<contact>" : "");
fprintf (out, "\n");
}
@@ -372,9 +372,9 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
/* Is this a quoted or an unquoted separator we are dealing with? */
if (ut == g_utf8_get_char(text_model->sep) && index >= 0) {
- const EDestination *dest = e_select_names_model_get_destination (source, index);
+ const EABDestination *dest = e_select_names_model_get_destination (source, index);
if (dest) {
- const gchar *str = e_destination_get_textrep (dest, FALSE);
+ const gchar *str = eab_destination_get_textrep (dest, FALSE);
int j;
const char *jp;
@@ -400,8 +400,8 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
if (index == -1) {
EReposAbsolute repos;
- e_select_names_model_insert (source, 0, e_destination_new ());
- e_select_names_model_insert (source, 0, e_destination_new ());
+ e_select_names_model_insert (source, 0, eab_destination_new ());
+ e_select_names_model_insert (source, 0, eab_destination_new ());
repos.model = model;
repos.pos = -1; /* At end */
@@ -420,7 +420,7 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
(e_select_names_model_get_string (source, ins_point) == NULL))
|| (ins_point > 0 && (e_select_names_model_get_string (source, ins_point-1) == NULL)))) {
- e_select_names_model_insert (source, ins_point, e_destination_new ());
+ e_select_names_model_insert (source, ins_point, eab_destination_new ());
repos.model = model;
repos.pos = pos;
@@ -435,10 +435,10 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
const gchar *str = e_select_names_model_get_string (source, index);
gchar *str1 = g_strndup (str, offset);
gchar *str2 = g_strdup (str+offset);
- EDestination *d1 = e_destination_new (), *d2 = e_destination_new ();
+ EABDestination *d1 = eab_destination_new (), *d2 = eab_destination_new ();
- e_destination_set_raw (d1, str1);
- e_destination_set_raw (d2, str2);
+ eab_destination_set_raw (d1, str1);
+ eab_destination_set_raw (d2, str2);
e_select_names_model_replace (source, index, d1);
e_select_names_model_insert (source, index+1, d2);
@@ -498,9 +498,9 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
if (new_str->len) {
- EDestination *dest;
- dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new ();
- e_destination_set_raw (dest, new_str->str);
+ EABDestination *dest;
+ dest = index >= 0 ? eab_destination_copy (e_select_names_model_get_destination (source, index)) : eab_destination_new ();
+ eab_destination_set_raw (dest, new_str->str);
e_select_names_model_replace (source, index, dest);
/* e_select_names_model_replace (source, index, dest); */
@@ -589,7 +589,7 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length)
if (index+1 < e_select_names_model_count (source)) {
EReposDeleteShift repos;
- EDestination *new_dest;
+ EABDestination *new_dest;
const gchar *str1 = e_select_names_model_get_string (source, index);
const gchar *str2 = e_select_names_model_get_string (source, index+1);
gchar *new_str;
@@ -613,8 +613,8 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length)
e_select_names_model_delete (source, index+1);
- new_dest = e_destination_new ();
- e_destination_set_raw (new_dest, new_str);
+ new_dest = eab_destination_new ();
+ eab_destination_set_raw (new_dest, new_str);
e_select_names_model_replace (source, index, new_dest);
g_free (new_str);
@@ -689,7 +689,7 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length)
char *np;
int i;
EReposDeleteShift repos;
- EDestination *dest;
+ EABDestination *dest;
new_str = g_new0 (char, strlen (str) * 6 + 1); /* worse case it can't be any longer than this */
@@ -718,8 +718,8 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length)
np = g_utf8_next_char (np);
}
- dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new ();
- e_destination_set_raw (dest, new_str);
+ dest = index >= 0 ? eab_destination_copy (e_select_names_model_get_destination (source, index)) : eab_destination_new ();
+ eab_destination_set_raw (dest, new_str);
e_select_names_model_replace (source, index, dest);
if (out)
@@ -764,10 +764,10 @@ e_select_names_text_model_obj_count (ETextModel *model)
count = i = e_select_names_model_count (source);
while (i > 0) {
- const EDestination *dest;
+ const EABDestination *dest;
--i;
dest = e_select_names_model_get_destination (source, i);
- if (e_destination_get_card (dest) == NULL)
+ if (eab_destination_get_contact (dest) == NULL)
--count;
}
@@ -783,8 +783,8 @@ nth_obj_index (ESelectNamesModel *source, gint n)
N = e_select_names_model_count (source);
do {
- const EDestination *dest = e_select_names_model_get_destination (source, i);
- if (e_destination_get_card (dest))
+ const EABDestination *dest = e_select_names_model_get_destination (source, i);
+ if (eab_destination_get_contact (dest))
--n;
++i;
} while (n >= 0 && i < N);
@@ -820,27 +820,32 @@ e_select_names_text_model_get_nth_obj (ETextModel *model, gint n, gint *len)
static void
e_select_names_text_model_activate_obj (ETextModel *model, gint n)
{
+#if notyet
+ /* XXX the new ebook doesn't have e_contact_get_book, and we
+ don't really want to add it, so this can't be implemented
+ this simply anymore */
ESelectNamesModel *source = E_SELECT_NAMES_TEXT_MODEL (model)->source;
- ECard *card;
+ EContact *contact;
gint i;
i = nth_obj_index (source, n);
g_return_if_fail (i >= 0);
- card = e_select_names_model_get_card (source, i);
- g_return_if_fail (card != NULL);
+ contact = e_select_names_model_get_contact (source, i);
+ g_return_if_fail (contact != NULL);
/* present read-only contact editor when someone double clicks from here */
- if (e_card_evolution_list (card)) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
EContactListEditor *ce;
- ce = e_addressbook_show_contact_list_editor (e_card_get_book(card), card, FALSE, FALSE);
+ ce = e_addressbook_show_contact_list_editor (e_contact_get_book(contact), contact, FALSE, FALSE);
e_contact_list_editor_raise (ce);
}
else {
- EContactEditor *ce;
- ce = e_addressbook_show_contact_editor (e_card_get_book(card), card, FALSE, FALSE);
+ EABContactEditor *ce;
+ ce = e_addressbook_show_contact_editor (e_contact_get_book(contact), contact, FALSE, FALSE);
e_contact_editor_raise (ce);
}
+#endif
}
diff --git a/addressbook/gui/component/select-names/e-select-names.c b/addressbook/gui/component/select-names/e-select-names.c
index f009fbbd63..b50a6d0ca0 100644
--- a/addressbook/gui/component/select-names/e-select-names.c
+++ b/addressbook/gui/component/select-names/e-select-names.c
@@ -30,9 +30,8 @@
#include <addressbook/gui/widgets/e-addressbook-model.h>
#include <addressbook/gui/widgets/e-addressbook-table-adapter.h>
-#include <addressbook/gui/component/e-cardlist-model.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
+#include <addressbook/backend/ebook/e-book-async.h>
+#include <addressbook/util/eab-book-util.h>
#include <addressbook/gui/component/addressbook-component.h>
#include <addressbook/gui/component/addressbook-storage.h>
#include <addressbook/gui/component/addressbook.h>
@@ -40,7 +39,7 @@
#include <shell/evolution-folder-selector-button.h>
#include "e-select-names.h"
-#include <addressbook/backend/ebook/e-card-simple.h>
+#include <addressbook/backend/ebook/e-contact.h>
#include "e-select-names-table-model.h"
#include <gal/widgets/e-categories-master-list-option-menu.h>
#include <gal/e-text/e-entry.h>
@@ -113,7 +112,7 @@ GtkWidget *e_addressbook_create_ebook_table(char *name, char *string1, char *str
GtkWidget *e_addressbook_create_folder_selector(char *name, char *string1, char *string2, int num1, int num2);
static void
-search_result (EAddressbookModel *model, EBookViewStatus status, ESelectNames *esn)
+search_result (EABModel *model, EBookViewStatus status, ESelectNames *esn)
{
sync_table_and_models (NULL, esn);
}
@@ -131,19 +130,15 @@ set_book(EBook *book, EBookStatus status, ESelectNames *esn)
}
static void
-addressbook_model_set_uri(ESelectNames *e_select_names, EAddressbookModel *model, const char *uri)
+addressbook_model_set_uri(ESelectNames *e_select_names, EABModel *model, const char *uri)
{
EBook *book;
- char *book_uri;
-
- book_uri = e_book_expand_uri (uri);
/* If uri == the current uri, then we don't have to do anything */
- book = e_addressbook_model_get_ebook (model);
+ book = eab_model_get_ebook (model);
if (book) {
const gchar *current_uri = e_book_get_uri (book);
- if (current_uri && !strcmp (book_uri, current_uri)) {
- g_free (book_uri);
+ if (current_uri && !strcmp (uri, current_uri)) {
return;
}
}
@@ -152,25 +147,28 @@ addressbook_model_set_uri(ESelectNames *e_select_names, EAddressbookModel *model
g_object_ref(e_select_names);
g_object_ref(model);
- addressbook_load_uri(book, book_uri, (EBookCallback) set_book, e_select_names);
-
- g_free (book_uri);
+ addressbook_load_uri(book, uri, (EBookCallback) set_book, e_select_names);
}
static void *
-card_key (ECard *card)
+contact_key (const EContact *contact)
{
- EBook *book;
+ EBook *book = NULL;
const gchar *book_uri;
- if (card == NULL)
+ if (contact == NULL)
return NULL;
- g_assert (E_IS_CARD (card));
+ g_assert (E_IS_CONTACT (contact));
- book = e_card_get_book (card);
+#if notyet
+ /* XXX we need a way to reproduce this here somehow.. or at
+ least make sure we never collide between two contacts in
+ different books. */
+ book = e_contact_get_book (contact);
+#endif
book_uri = book ? e_book_get_uri (book) : "NoBook";
- return g_strdup_printf ("%s|%s", book_uri ? book_uri : "NoURI", e_card_get_id (card));
+ return g_strdup_printf ("%s|%s", book_uri ? book_uri : "NoURI", (char*)e_contact_get_const ((EContact*)contact, E_CONTACT_UID));
}
static void
@@ -180,14 +178,14 @@ sync_one_model (gpointer k, gpointer val, gpointer closure)
ESelectNamesChild *child = val;
ESelectNamesModel *model = child->source;
gint i, count;
- ECard *card;
+ EContact *contact;
void *key;
count = e_select_names_model_count (model);
for (i = 0; i < count; ++i) {
- card = e_select_names_model_get_card (model, i);
- if (card) {
- key = card_key (card);
+ contact = e_select_names_model_get_contact (model, i);
+ if (contact) {
+ key = contact_key (contact);
e_table_without_hide (etw, key);
g_free (key);
}
@@ -206,21 +204,19 @@ real_add_address_cb (int model_row, gpointer closure)
{
ESelectNamesChild *child = closure;
ESelectNames *names = child->names;
- ECard *card;
- EDestination *dest = e_destination_new ();
+ const EContact *contact;
+ EABDestination *dest = eab_destination_new ();
gint mapped_row;
mapped_row = e_table_subset_view_to_model_row (E_TABLE_SUBSET (names->without), model_row);
- card = e_addressbook_model_get_card (E_ADDRESSBOOK_MODEL(names->model), mapped_row);
+ contact = eab_model_contact_at (EAB_MODEL(names->model), mapped_row);
- if (card != NULL) {
- e_destination_set_card (dest, card, 0);
+ if (contact != NULL) {
+ eab_destination_set_contact (dest, (EContact*)contact, 0);
e_select_names_model_append (child->source, dest);
e_select_names_model_clean (child->source, FALSE);
-
- g_object_unref(card);
}
}
@@ -266,10 +262,9 @@ selection_change (ETable *table, ESelectNames *names)
static void *
esn_get_key_fn (ETableModel *source, int row, void *closure)
{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL (closure);
- ECard *card = e_addressbook_model_get_card (model, row);
- void *key = card_key (card);
- g_object_unref (card);
+ EABModel *model = EAB_MODEL (closure);
+ const EContact *contact = eab_model_contact_at (model, row);
+ void *key = contact_key (contact);
return key;
}
@@ -297,11 +292,11 @@ e_addressbook_create_ebook_table(char *name, char *string1, char *string2, int n
{
ETableModel *adapter;
ETableModel *without;
- EAddressbookModel *model;
+ EABModel *model;
GtkWidget *table;
- model = e_addressbook_model_new ();
- adapter = E_TABLE_MODEL (e_addressbook_table_adapter_new (model));
+ model = eab_model_new ();
+ adapter = E_TABLE_MODEL (eab_table_adapter_new (model));
g_object_set(model,
"editable", FALSE,
@@ -340,7 +335,7 @@ folder_selected (EvolutionFolderSelectorButton *button, GNOME_Evolution_Folder *
{
addressbook_model_set_uri(e_select_names, e_select_names->model, folder->physicalUri);
- e_config_listener_set_string (e_book_get_config_database(),
+ e_config_listener_set_string (eab_get_config_database(),
"/apps/evolution/addressbook/select_names/last_used_uri", folder->physicalUri);
}
@@ -392,7 +387,7 @@ update_query (GtkWidget *widget, ESelectNames *e_select_names)
}
static void
-status_message (EAddressbookModel *model, const gchar *message, ESelectNames *e_select_names)
+status_message (EABModel *model, const gchar *message, ESelectNames *e_select_names)
{
if (message == NULL)
gtk_label_set_text (GTK_LABEL (e_select_names->status_message), "");
@@ -424,7 +419,7 @@ select_entry_changed (GtkWidget *widget, ESelectNames *e_select_names)
int model_row = e_table_view_to_model_row (table, i);
char *row_strcoll_string =
g_utf8_collate_key (e_table_model_value_at (e_select_names->without,
- E_CARD_SIMPLE_FIELD_NAME_OR_ORG,
+ E_CONTACT_FULL_NAME,
model_row),
-1);
if (g_utf8_collate (select_strcoll_string, row_strcoll_string) <= 0) {
@@ -637,12 +632,14 @@ e_select_names_new (EvolutionShellClient *shell_client)
e_select_names = g_object_new (E_TYPE_SELECT_NAMES, NULL);
- db = e_book_get_config_database ();
+ db = eab_get_config_database ();
contacts_uri = e_config_listener_get_string_with_default (
db, "/apps/evolution/addressbook/select_names/last_used_uri",
NULL, NULL);
+#if notyet
if (!contacts_uri)
contacts_uri = g_strdup (e_book_get_default_book_uri ());
+#endif
button = glade_xml_get_widget (e_select_names->gui, "folder-selector");
evolution_folder_selector_button_construct (EVOLUTION_FOLDER_SELECTOR_BUTTON (button),
diff --git a/addressbook/gui/component/select-names/e-select-names.h b/addressbook/gui/component/select-names/e-select-names.h
index 8e672da92a..e67f64b70b 100644
--- a/addressbook/gui/component/select-names/e-select-names.h
+++ b/addressbook/gui/component/select-names/e-select-names.h
@@ -67,7 +67,7 @@ struct _ESelectNames
ETableScrolled *table;
ETableModel *adapter;
ETableModel *without;
- EAddressbookModel *model;
+ EABModel *model;
GtkWidget *categories;
GtkWidget *select_entry;
GtkWidget *status_message;
diff --git a/addressbook/gui/component/select-names/e-simple-card-bonobo.c b/addressbook/gui/component/select-names/e-simple-card-bonobo.c
deleted file mode 100644
index 07203618b3..0000000000
--- a/addressbook/gui/component/select-names/e-simple-card-bonobo.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-simple-card-bonobo.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- * Chris Lahey <clahey@ximian.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-simple-card-bonobo.h"
-
-#include <gal/util/e-util.h>
-
-#include "Evolution-Addressbook-SelectNames.h"
-
-
-#define PARENT_TYPE BONOBO_TYPE_OBJECT
-static BonoboObjectClass *parent_class = NULL;
-
-struct _ESimpleCardBonoboPrivate {
- ECardSimple *card_simple;
-};
-
-
-
-static GNOME_Evolution_Addressbook_SimpleCard_Arbitrary *
-impl_SimpleCard_get_arbitrary (PortableServer_Servant servant,
- const CORBA_char *key,
- CORBA_Environment *ev)
-{
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
- GNOME_Evolution_Addressbook_SimpleCard_Arbitrary *ret_val = GNOME_Evolution_Addressbook_SimpleCard_Arbitrary__alloc ();
-
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object (servant));
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- const ECardArbitrary *arbitrary = e_card_simple_get_arbitrary (priv->card_simple, key);
- ret_val->key = CORBA_string_dup (arbitrary->key);
- ret_val->value = CORBA_string_dup (arbitrary->value);
- ret_val->type = CORBA_string_dup (arbitrary->type);
- } else {
- ret_val->key = CORBA_string_dup ("");
- ret_val->value = CORBA_string_dup ("");
- ret_val->type = CORBA_string_dup ("");
- }
-
- return ret_val;
-}
-
-static void
-impl_SimpleCard_set_arbitrary (PortableServer_Servant servant,
- const CORBA_char *key,
- const CORBA_char *type,
- const CORBA_char *value,
- CORBA_Environment *ev)
-{
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object (servant));
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- e_card_simple_set_arbitrary (priv->card_simple, key, type, value);
- }
-}
-
-static CORBA_char *
-impl_SimpleCard_get (PortableServer_Servant servant,
- GNOME_Evolution_Addressbook_SimpleCard_Field field,
- CORBA_Environment *ev)
-{
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object (servant));
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- char *value = e_card_simple_get (priv->card_simple,
- field);
- char *ret_val = CORBA_string_dup (value ? value : "");
- g_free (value);
- return ret_val;
- } else {
- return CORBA_string_dup ("");
- }
-}
-
-static void
-impl_SimpleCard_set (PortableServer_Servant servant,
- GNOME_Evolution_Addressbook_SimpleCard_Field field,
- const CORBA_char *value,
- CORBA_Environment *ev)
-{
-
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object (servant));
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- e_card_simple_set (priv->card_simple,
- field,
- value);
- }
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- simple_card = E_SIMPLE_CARD_BONOBO (object);
- priv = simple_card->priv;
-
- if (priv) {
- if (priv->card_simple) {
- g_object_unref (priv->card_simple);
- }
-
- g_free (priv);
- simple_card->priv = NULL;
- }
-
- if (G_OBJECT_CLASS(parent_class)->dispose)
- G_OBJECT_CLASS(parent_class)->dispose(object);
-}
-
-
-static void
-e_simple_card_bonobo_class_init (ESimpleCardBonoboClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_Addressbook_SimpleCard__epv *epv;
-
- object_class = G_OBJECT_CLASS (klass);
- parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT);
-
- object_class->dispose = impl_dispose;
-
- epv = &klass->epv;
- epv->getArbitrary = impl_SimpleCard_get_arbitrary;
- epv->setArbitrary = impl_SimpleCard_set_arbitrary;
- epv->get = impl_SimpleCard_get;
- epv->set = impl_SimpleCard_set;
-}
-
-static void
-e_simple_card_bonobo_init (ESimpleCardBonobo *simple_card)
-{
- ESimpleCardBonoboPrivate *priv;
-
- priv = g_new (ESimpleCardBonoboPrivate, 1);
-
- priv->card_simple = NULL;
-
- simple_card->priv = priv;
-}
-
-
-void
-e_simple_card_bonobo_construct (ESimpleCardBonobo *simple_card,
- ECardSimple *card_simple)
-{
- g_return_if_fail (simple_card != NULL);
- g_return_if_fail (E_IS_SIMPLE_CARD_BONOBO (simple_card));
-
- simple_card->priv->card_simple = card_simple;
- g_object_ref (card_simple);
-}
-
-ESimpleCardBonobo *
-e_simple_card_bonobo_new (ECardSimple *card_simple)
-{
- ESimpleCardBonobo *simple_card;
-
- simple_card = g_object_new (E_TYPE_SIMPLE_CARD_BONOBO, NULL);
-
- e_simple_card_bonobo_construct (simple_card, card_simple);
-
- return simple_card;
-}
-
-
-BONOBO_TYPE_FUNC_FULL (
- ESimpleCardBonobo,
- GNOME_Evolution_Addressbook_SimpleCard,
- PARENT_TYPE,
- e_simple_card_bonobo);
diff --git a/addressbook/gui/component/select-names/e-simple-card-bonobo.h b/addressbook/gui/component/select-names/e-simple-card-bonobo.h
deleted file mode 100644
index 7bc2d65830..0000000000
--- a/addressbook/gui/component/select-names/e-simple-card-bonobo.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-simple-card-bonobo.h
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- * Chris Lahey <clahey@ximian.com>
- */
-
-#ifndef __E_SIMPLE_CARD_BONOBO_H__
-#define __E_SIMPLE_CARD_BONOBO_H__
-
-#include <bonobo/bonobo-object.h>
-
-#include "Evolution-Addressbook-SelectNames.h"
-#include <addressbook/backend/ebook/e-card-simple.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define E_TYPE_SIMPLE_CARD_BONOBO (e_simple_card_bonobo_get_type ())
-#define E_SIMPLE_CARD_BONOBO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SIMPLE_CARD_BONOBO, ESimpleCardBonobo))
-#define E_SIMPLE_CARD_BONOBO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SIMPLE_CARD_BONOBO, ESimpleCardBonoboClass))
-#define E_IS_SIMPLE_CARD_BONOBO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SIMPLE_CARD_BONOBO))
-#define E_IS_SIMPLE_CARD_BONOBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_SIMPLE_CARD_BONOBO))
-
-
-typedef struct _ESimpleCardBonobo ESimpleCardBonobo;
-typedef struct _ESimpleCardBonoboPrivate ESimpleCardBonoboPrivate;
-typedef struct _ESimpleCardBonoboClass ESimpleCardBonoboClass;
-
-struct _ESimpleCardBonobo {
- BonoboObject parent;
-
- ESimpleCardBonoboPrivate *priv;
-};
-
-struct _ESimpleCardBonoboClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Addressbook_SimpleCard__epv epv;
-};
-
-
-GType e_simple_card_bonobo_get_type (void);
-ESimpleCardBonobo *e_simple_card_bonobo_new (ECardSimple *card_simple);
-void e_simple_card_bonobo_construct (ESimpleCardBonobo *simple_card,
- ECardSimple *card_simple);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_SIMPLE_CARD_BONOBO_H__ */
diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am
index fc3a0a71d0..ae9f99cd35 100644
--- a/addressbook/gui/contact-editor/Makefile.am
+++ b/addressbook/gui/contact-editor/Makefile.am
@@ -29,8 +29,6 @@ libecontacteditor_la_SOURCES = \
e-contact-editor-marshal.c \
e-contact-editor.c \
e-contact-editor.h \
- e-contact-save-as.c \
- e-contact-save-as.h \
e-contact-quick-add.c \
e-contact-quick-add.h
diff --git a/addressbook/gui/contact-editor/contact-editor.glade b/addressbook/gui/contact-editor/contact-editor.glade
index 2ef6954d10..10b05c27b4 100644
--- a/addressbook/gui/contact-editor/contact-editor.glade
+++ b/addressbook/gui/contact-editor/contact-editor.glade
@@ -1478,6 +1478,49 @@
<property name="y_options">fill</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkLabel" id="accellabel-blog">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Blog address:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">1</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">entry-web</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="entry-blog">
+ <property name="visible">True</property>
+ <property name="creation_function">e_contact_editor_create_web</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Sat, 08 Feb 2003 09:14:46 GMT</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="tab_expand">False</property>
diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.c b/addressbook/gui/contact-editor/e-contact-editor-address.c
index da8bb5421f..34977e3fb7 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-address.c
+++ b/addressbook/gui/contact-editor/e-contact-editor-address.c
@@ -420,7 +420,9 @@ e_contact_editor_address_init (EContactEditorAddress *e_contact_editor_address)
gtk_window_set_resizable(GTK_WINDOW(e_contact_editor_address), TRUE);
+#if notyet
e_contact_editor_address->address = NULL;
+#endif
gui = glade_xml_new (EVOLUTION_GLADEDIR "/fulladdr.glade", NULL, NULL);
e_contact_editor_address->gui = gui;
@@ -453,22 +455,26 @@ e_contact_editor_address_dispose (GObject *object)
e_contact_editor_address->gui = NULL;
}
+#if notyet
if (e_contact_editor_address->address) {
e_card_delivery_address_unref(e_contact_editor_address->address);
e_contact_editor_address->address = NULL;
}
+#endif
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
GtkWidget*
-e_contact_editor_address_new (const ECardDeliveryAddress *address)
+e_contact_editor_address_new (/* XXX notyet const ECardDeliveryAddress *address*/)
{
GtkWidget *widget = g_object_new (E_TYPE_CONTACT_EDITOR_ADDRESS, NULL);
+#if notyet
g_object_set (widget,
"address", address,
NULL);
+#endif
return widget;
}
@@ -482,9 +488,11 @@ e_contact_editor_address_set_property (GObject *object, guint prop_id,
switch (prop_id){
case PROP_ADDRESS:
+#if notyet
e_card_delivery_address_unref(e_contact_editor_address->address);
e_contact_editor_address->address = e_card_delivery_address_copy(g_value_get_pointer (value));
fill_in_info(e_contact_editor_address);
+#endif
break;
case PROP_EDITABLE: {
int i;
@@ -540,7 +548,9 @@ e_contact_editor_address_get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_ADDRESS:
extract_info(e_contact_editor_address);
+#if notyet
g_value_set_pointer (value, e_card_delivery_address_ref(e_contact_editor_address->address));
+#endif
break;
case PROP_EDITABLE:
g_value_set_boolean (value, e_contact_editor_address->editable ? TRUE : FALSE);
@@ -566,6 +576,7 @@ fill_in_field(EContactEditorAddress *editor, char *field, char *string)
static void
fill_in_info(EContactEditorAddress *editor)
{
+#if notyet
ECardDeliveryAddress *address = editor->address;
if (address) {
fill_in_field(editor, "entry-street" , address->street );
@@ -576,6 +587,7 @@ fill_in_info(EContactEditorAddress *editor)
fill_in_field(editor, "entry-code" , address->code );
fill_in_field(editor, "entry-country", address->country);
}
+#endif
}
static char *
@@ -591,6 +603,7 @@ extract_field(EContactEditorAddress *editor, char *field)
static void
extract_info(EContactEditorAddress *editor)
{
+#if notyet
ECardDeliveryAddress *address = editor->address;
if (!address) {
address = e_card_delivery_address_new();
@@ -603,4 +616,5 @@ extract_info(EContactEditorAddress *editor)
address->region = extract_field(editor, "entry-region" );
address->code = extract_field(editor, "entry-code" );
address->country = extract_field(editor, "entry-country");
+#endif
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.h b/addressbook/gui/contact-editor/e-contact-editor-address.h
index 7faab47a4f..c20f020152 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-address.h
+++ b/addressbook/gui/contact-editor/e-contact-editor-address.h
@@ -22,7 +22,7 @@
#include <gtk/gtkdialog.h>
#include <glade/glade.h>
-#include <ebook/e-card.h>
+#include <ebook/e-contact.h>
G_BEGIN_DECLS
@@ -49,8 +49,10 @@ struct _EContactEditorAddress
{
GtkDialog parent;
+#if notyet
/* item specific fields */
ECardDeliveryAddress *address;
+#endif
guint editable : 1;
@@ -63,7 +65,7 @@ struct _EContactEditorAddressClass
};
-GtkWidget *e_contact_editor_address_new(const ECardDeliveryAddress *name);
+GtkWidget *e_contact_editor_address_new(/* XXX not yet const ECardDeliveryAddress *name*/);
GType e_contact_editor_address_get_type (void);
G_END_DECLS
diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.c b/addressbook/gui/contact-editor/e-contact-editor-fullname.c
index 4a7d6cec1b..c37f4cc8b7 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-fullname.c
+++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.c
@@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-contact-editor-fullname.c
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
+ * eab-contact-editor-phones.c
+ * Copyright (C) 2003 Ximian, Inc.
+ * Author: Chris Toshok <toshok@ximian.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -142,7 +142,7 @@ e_contact_editor_fullname_dispose (GObject *object)
}
if (e_contact_editor_fullname->name) {
- e_card_name_unref(e_contact_editor_fullname->name);
+ e_contact_name_free(e_contact_editor_fullname->name);
e_contact_editor_fullname->name = NULL;
}
@@ -151,12 +151,12 @@ e_contact_editor_fullname_dispose (GObject *object)
}
GtkWidget*
-e_contact_editor_fullname_new (const ECardName *name)
+e_contact_editor_fullname_new (const EContactName *name)
{
GtkWidget *widget = g_object_new (E_TYPE_CONTACT_EDITOR_FULLNAME, NULL);
g_object_set (widget,
- "name", name,
- NULL);
+ "name", name,
+ NULL);
return widget;
}
@@ -170,8 +170,8 @@ e_contact_editor_fullname_set_property (GObject *object, guint prop_id,
switch (prop_id){
case PROP_NAME:
- e_card_name_unref(e_contact_editor_fullname->name);
- e_contact_editor_fullname->name = e_card_name_copy(g_value_get_pointer (value));
+ e_contact_name_free(e_contact_editor_fullname->name);
+ e_contact_editor_fullname->name = e_contact_name_copy(g_value_get_pointer (value));
fill_in_info(e_contact_editor_fullname);
break;
case PROP_EDITABLE: {
@@ -224,7 +224,7 @@ e_contact_editor_fullname_get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_NAME:
extract_info(e_contact_editor_fullname);
- g_value_set_pointer (value, e_card_name_ref(e_contact_editor_fullname->name));
+ g_value_set_pointer (value, e_contact_name_copy(e_contact_editor_fullname->name));
break;
case PROP_EDITABLE:
g_value_set_boolean (value, e_contact_editor_fullname->editable ? TRUE : FALSE);
@@ -250,13 +250,13 @@ fill_in_field(EContactEditorFullname *editor, char *field, char *string)
static void
fill_in_info(EContactEditorFullname *editor)
{
- ECardName *name = editor->name;
+ EContactName *name = editor->name;
if (name) {
- fill_in_field(editor, "entry-title", name->prefix);
+ fill_in_field(editor, "entry-title", name->prefixes);
fill_in_field(editor, "entry-first", name->given);
fill_in_field(editor, "entry-middle", name->additional);
fill_in_field(editor, "entry-last", name->family);
- fill_in_field(editor, "entry-suffix", name->suffix);
+ fill_in_field(editor, "entry-suffix", name->suffixes);
}
}
@@ -273,15 +273,15 @@ extract_field(EContactEditorFullname *editor, char *field)
static void
extract_info(EContactEditorFullname *editor)
{
- ECardName *name = editor->name;
+ EContactName *name = editor->name;
if (!name) {
- name = e_card_name_new();
+ name = e_contact_name_new();
editor->name = name;
}
- name->prefix = extract_field(editor, "entry-title" );
+ name->prefixes = extract_field(editor, "entry-title" );
name->given = extract_field(editor, "entry-first" );
name->additional = extract_field(editor, "entry-middle");
name->family = extract_field(editor, "entry-last" );
- name->suffix = extract_field(editor, "entry-suffix");
+ name->suffixes = extract_field(editor, "entry-suffix");
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.h b/addressbook/gui/contact-editor/e-contact-editor-fullname.h
index 3c8e055a96..408fcffdc3 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-fullname.h
+++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.h
@@ -22,7 +22,7 @@
#include <gtk/gtkdialog.h>
#include <glade/glade.h>
-#include <ebook/e-card.h>
+#include <ebook/e-contact.h>
G_BEGIN_DECLS
@@ -50,7 +50,7 @@ struct _EContactEditorFullname
GtkDialog parent;
/* item specific fields */
- ECardName *name;
+ EContactName *name;
GladeXML *gui;
/* Whether the dialog will accept modifications */
@@ -63,7 +63,7 @@ struct _EContactEditorFullnameClass
};
-GtkWidget *e_contact_editor_fullname_new(const ECardName *name);
+GtkWidget *e_contact_editor_fullname_new(const EContactName *name);
GType e_contact_editor_fullname_get_type (void);
G_END_DECLS
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index 2330daf063..1391ccf1b0 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -49,29 +49,28 @@
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
-#include "addressbook/gui/widgets/e-addressbook-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
#include "e-util/e-gui-utils.h"
#include "widgets/misc/e-dateedit.h"
#include "widgets/misc/e-url-entry.h"
#include "shell/evolution-shell-component-utils.h"
-#include "e-card-merging.h"
+#include "eab-contact-merging.h"
#include "e-contact-editor-address.h"
#include "e-contact-editor-fullname.h"
#include "e-contact-editor-marshal.h"
-#include "e-contact-save-as.h"
/* Signal IDs */
enum {
- CARD_ADDED,
- CARD_MODIFIED,
- CARD_DELETED,
+ CONTACT_ADDED,
+ CONTACT_MODIFIED,
+ CONTACT_DELETED,
EDITOR_CLOSED,
LAST_SIGNAL
};
-static void e_contact_editor_init (EContactEditor *card);
+static void e_contact_editor_init (EContactEditor *editor);
static void e_contact_editor_class_init (EContactEditorClass *klass);
static void e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void e_contact_editor_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
@@ -85,9 +84,10 @@ static void enable_writable_fields(EContactEditor *editor);
static void set_editable(EContactEditor *editor);
static void fill_in_info(EContactEditor *editor);
static void extract_info(EContactEditor *editor);
-static void set_fields(EContactEditor *editor);
+static void set_field(EContactEditor *editor, GtkEntry *entry, const char *string);
static void set_address_field(EContactEditor *editor, int result);
-static void add_field_callback(GtkWidget *widget, EContactEditor *editor);
+static void set_phone_field(EContactEditor *editor, GtkWidget *entry, const char *phone_number);
+static void set_fields(EContactEditor *editor);
static void command_state_changed (EContactEditor *ce);
static void widget_changed (GtkWidget *widget, EContactEditor *editor);
static void close_dialog (EContactEditor *ce);
@@ -101,8 +101,8 @@ static guint contact_editor_signals[LAST_SIGNAL];
enum {
PROP_0,
PROP_BOOK,
- PROP_CARD,
- PROP_IS_NEW_CARD,
+ PROP_CONTACT,
+ PROP_IS_NEW_CONTACT,
PROP_EDITABLE,
PROP_CHANGED,
PROP_WRITABLE_FIELDS
@@ -114,6 +114,34 @@ enum {
DYNAMIC_LIST_ADDRESS
};
+static EContactField phones[] = {
+ E_CONTACT_PHONE_ASSISTANT,
+ E_CONTACT_PHONE_BUSINESS,
+ E_CONTACT_PHONE_BUSINESS_2,
+ E_CONTACT_PHONE_BUSINESS_FAX,
+ E_CONTACT_PHONE_CALLBACK,
+ E_CONTACT_PHONE_CAR,
+ E_CONTACT_PHONE_COMPANY,
+ E_CONTACT_PHONE_HOME,
+ E_CONTACT_PHONE_HOME_2,
+ E_CONTACT_PHONE_HOME_FAX,
+ E_CONTACT_PHONE_ISDN,
+ E_CONTACT_PHONE_MOBILE,
+ E_CONTACT_PHONE_OTHER,
+ E_CONTACT_PHONE_OTHER_FAX,
+ E_CONTACT_PHONE_PAGER,
+ E_CONTACT_PHONE_PRIMARY,
+ E_CONTACT_PHONE_RADIO,
+ E_CONTACT_PHONE_TELEX,
+ E_CONTACT_PHONE_TTYTDD,
+};
+
+static EContactField emails[] = {
+ E_CONTACT_EMAIL_1,
+ E_CONTACT_EMAIL_2,
+ E_CONTACT_EMAIL_3
+};
+
static GSList *all_contact_editors = NULL;
GType
@@ -158,16 +186,16 @@ e_contact_editor_class_init (EContactEditorClass *klass)
E_TYPE_BOOK,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class, PROP_CARD,
- g_param_spec_object ("card",
- _("Card"),
+ g_object_class_install_property (object_class, PROP_CONTACT,
+ g_param_spec_object ("contact",
+ _("Contact"),
/*_( */"XXX blurb" /*)*/,
- E_TYPE_CARD,
+ E_TYPE_CONTACT,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class, PROP_IS_NEW_CARD,
- g_param_spec_boolean ("is_new_card",
- _("Is New Card"),
+ g_object_class_install_property (object_class, PROP_IS_NEW_CONTACT,
+ g_param_spec_boolean ("is_new_contact",
+ _("Is New Contact"),
/*_( */"XXX blurb" /*)*/,
FALSE,
G_PARAM_READWRITE));
@@ -193,31 +221,31 @@ e_contact_editor_class_init (EContactEditorClass *klass)
FALSE,
G_PARAM_READWRITE));
- contact_editor_signals[CARD_ADDED] =
- g_signal_new ("card_added",
+ contact_editor_signals[CONTACT_ADDED] =
+ g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EContactEditorClass, card_added),
+ G_STRUCT_OFFSET (EContactEditorClass, contact_added),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- contact_editor_signals[CARD_MODIFIED] =
- g_signal_new ("card_modified",
+ contact_editor_signals[CONTACT_MODIFIED] =
+ g_signal_new ("contact_modified",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EContactEditorClass, card_modified),
+ G_STRUCT_OFFSET (EContactEditorClass, contact_modified),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- contact_editor_signals[CARD_DELETED] =
- g_signal_new ("card_deleted",
+ contact_editor_signals[CONTACT_DELETED] =
+ g_signal_new ("contact_deleted",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EContactEditorClass, card_deleted),
+ G_STRUCT_OFFSET (EContactEditorClass, contact_deleted),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
@@ -259,11 +287,10 @@ wants_html_changed (GtkWidget *widget, EContactEditor *editor)
{
gboolean wants_html;
g_object_get (widget,
- "active", &wants_html,
- NULL);
- g_object_set (editor->card,
- "wants_html", wants_html,
- NULL);
+ "active", &wants_html,
+ NULL);
+
+ e_contact_set (editor->contact, E_CONTACT_WANTS_HTML, GINT_TO_POINTER (wants_html));
widget_changed (widget, editor);
}
@@ -273,23 +300,20 @@ phone_entry_changed (GtkWidget *widget, EContactEditor *editor)
{
int which;
GtkEntry *entry = GTK_ENTRY(widget);
- ECardPhone *phone;
- if ( widget == glade_xml_get_widget(editor->gui, "entry-phone1") ) {
+ if ( widget == glade_xml_get_widget(editor->gui, "entry-phone1") )
which = 1;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone2") ) {
+ else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone2") )
which = 2;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone3") ) {
+ else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone3") )
which = 3;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone4") ) {
+ else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone4") )
which = 4;
- } else
+ else
return;
- phone = e_card_phone_new();
- phone->number = g_strdup (gtk_entry_get_text(entry));
- e_card_simple_set_phone(editor->simple, editor->phone_choice[which - 1], phone);
- e_card_phone_unref(phone);
- set_fields(editor);
+
+ printf ("gtk_entry_get_text(entry) == %s\n", (char*)gtk_entry_get_text(entry));
+ e_contact_set(editor->contact, editor->phone_choice[which - 1], (char*)gtk_entry_get_text(entry));
widget_changed (widget, editor);
}
@@ -297,12 +321,9 @@ phone_entry_changed (GtkWidget *widget, EContactEditor *editor)
static void
email_entry_changed (GtkWidget *widget, EContactEditor *editor)
{
- const gchar *string;
GtkEntry *entry = GTK_ENTRY(widget);
- string = gtk_entry_get_text(entry);
-
- e_card_simple_set_email(editor->simple, editor->email_choice, string);
+ e_contact_set (editor->contact, editor->email_choice, (char*)gtk_entry_get_text(entry));
widget_changed (widget, editor);
}
@@ -310,6 +331,7 @@ email_entry_changed (GtkWidget *widget, EContactEditor *editor)
static void
address_text_changed (GtkTextBuffer *buffer, EContactEditor *editor)
{
+#if notyet
ECardAddrLabel *address;
GtkTextIter start_iter, end_iter;
@@ -346,12 +368,14 @@ address_text_changed (GtkTextBuffer *buffer, EContactEditor *editor)
e_card_address_label_unref(address);
widget_changed (NULL, editor);
+#endif
}
static void
address_mailing_changed (GtkWidget *widget, EContactEditor *editor)
{
+#if notyet
const ECardDeliveryAddress *curr;
ECardDeliveryAddress *address;
gboolean mailing_address;
@@ -399,12 +423,13 @@ address_mailing_changed (GtkWidget *widget, EContactEditor *editor)
editor->address_mailing = -1;
widget_changed (widget, editor);
+#endif
}
/* This function tells you whether name_to_style will make sense. */
static gboolean
-style_makes_sense(const ECardName *name, char *company, int style)
+style_makes_sense(const EContactName *name, char *company, int style)
{
switch (style) {
case 0: /* Fall Through */
@@ -427,7 +452,7 @@ style_makes_sense(const ECardName *name, char *company, int style)
}
static char *
-name_to_style(const ECardName *name, char *company, int style)
+name_to_style(const EContactName *name, char *company, int style)
{
char *string;
char *strings[4], **stringptr;
@@ -489,7 +514,7 @@ file_as_get_style (EContactEditor *editor)
GtkEntry *file_as = GTK_ENTRY(glade_xml_get_widget(editor->gui, "entry-file-as"));
char *filestring;
char *trystring;
- ECardName *name = editor->name;
+ EContactName *name = editor->name;
int i;
int style;
@@ -561,11 +586,12 @@ name_entry_changed (GtkWidget *widget, EContactEditor *editor)
const char *string;
style = file_as_get_style(editor);
-
- e_card_name_unref(editor->name);
+
+ e_contact_name_free (editor->name);
string = gtk_entry_get_text (GTK_ENTRY(widget));
- editor->name = e_card_name_from_string(string);
+
+ editor->name = e_contact_name_from_string(string);
file_as_set_style(editor, style);
@@ -680,6 +706,7 @@ set_entry_changed_signals(EContactEditor *editor)
}
set_urlentry_changed_signal_field (editor, "entry-web");
+ set_urlentry_changed_signal_field (editor, "entry-blog");
set_urlentry_changed_signal_field (editor, "entry-caluri");
set_urlentry_changed_signal_field (editor, "entry-fburl");
@@ -719,32 +746,32 @@ full_name_clicked(GtkWidget *button, EContactEditor *editor)
int result;
g_object_set (dialog,
- "editable", editor->fullname_editable,
- NULL);
+ "editable", editor->fullname_editable,
+ NULL);
gtk_widget_show(GTK_WIDGET(dialog));
result = gtk_dialog_run (dialog);
gtk_widget_hide (GTK_WIDGET (dialog));
if (editor->fullname_editable && result == GTK_RESPONSE_OK) {
- ECardName *name;
+ EContactName *name;
GtkWidget *fname_widget;
int style = 0;
g_object_get (dialog,
- "name", &name,
- NULL);
+ "name", &name,
+ NULL);
style = file_as_get_style(editor);
fname_widget = glade_xml_get_widget(editor->gui, "entry-fullname");
if (fname_widget && GTK_IS_ENTRY(fname_widget)) {
- char *full_name = e_card_name_to_string(name);
+ char *full_name = e_contact_name_to_string(name);
gtk_entry_set_text(GTK_ENTRY(fname_widget), full_name);
g_free(full_name);
}
- e_card_name_unref(editor->name);
- editor->name = e_card_name_ref(name);
+ e_contact_name_free(editor->name);
+ editor->name = name;
file_as_set_style(editor, style);
}
@@ -754,6 +781,7 @@ full_name_clicked(GtkWidget *button, EContactEditor *editor)
static void
full_addr_clicked(GtkWidget *button, EContactEditor *editor)
{
+#if notyet
GtkDialog *dialog;
int result;
const ECardDeliveryAddress *address;
@@ -802,6 +830,7 @@ full_addr_clicked(GtkWidget *button, EContactEditor *editor)
widget_changed (NULL, editor);
}
gtk_widget_destroy (GTK_WIDGET (dialog));
+#endif
}
static void
@@ -814,10 +843,9 @@ categories_clicked(GtkWidget *button, EContactEditor *editor)
ECategoriesMasterList *ecml;
if (entry && GTK_IS_ENTRY(entry))
categories = g_strdup (gtk_entry_get_text(GTK_ENTRY(entry)));
- else if (editor->card)
- g_object_get (editor->card,
- "categories", &categories,
- NULL);
+ else if (editor->contact)
+ categories = e_contact_get (editor->contact, E_CONTACT_CATEGORIES);
+
dialog = GTK_DIALOG(e_categories_new(categories));
if (dialog == NULL) {
@@ -841,14 +869,13 @@ categories_clicked(GtkWidget *button, EContactEditor *editor)
g_free (categories);
if (result == GTK_RESPONSE_OK) {
g_object_get (dialog,
- "categories", &categories,
- NULL);
+ "categories", &categories,
+ NULL);
if (entry && GTK_IS_ENTRY(entry))
gtk_entry_set_text(GTK_ENTRY(entry), categories);
else
- g_object_set (editor->card,
- "categories", categories,
- NULL);
+ e_contact_set (editor->contact, E_CONTACT_CATEGORIES, categories);
+
g_free(categories);
}
gtk_widget_destroy(GTK_WIDGET(dialog));
@@ -860,7 +887,7 @@ typedef struct {
} EditorCloseStruct;
static void
-card_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+contact_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
{
EContactEditor *ce = ecs->ce;
gboolean should_close = ecs->should_close;
@@ -868,13 +895,13 @@ card_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruc
gtk_widget_set_sensitive (ce->app, TRUE);
ce->in_async_call = FALSE;
- e_card_set_id (ce->card, id);
+ e_contact_set (ce->contact, E_CONTACT_UID, (char*)id);
- g_signal_emit (ce, contact_editor_signals[CARD_ADDED], 0,
- status, ce->card);
+ g_signal_emit (ce, contact_editor_signals[CONTACT_ADDED], 0,
+ status, ce->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
- ce->is_new_card = FALSE;
+ if (status == E_BOOK_ERROR_OK) {
+ ce->is_new_contact = FALSE;
if (should_close) {
close_dialog (ce);
@@ -890,7 +917,7 @@ card_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruc
}
static void
-card_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
+contact_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
{
EContactEditor *ce = ecs->ce;
gboolean should_close = ecs->should_close;
@@ -898,10 +925,10 @@ card_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
gtk_widget_set_sensitive (ce->app, TRUE);
ce->in_async_call = FALSE;
- g_signal_emit (ce, contact_editor_signals[CARD_MODIFIED], 0,
- status, ce->card);
+ g_signal_emit (ce, contact_editor_signals[CONTACT_MODIFIED], 0,
+ status, ce->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
if (should_close) {
close_dialog (ce);
}
@@ -915,12 +942,11 @@ card_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
g_free (ecs);
}
-/* Emits the signal to request saving a card */
+/* Emits the signal to request saving a contact */
static void
-save_card (EContactEditor *ce, gboolean should_close)
+save_contact (EContactEditor *ce, gboolean should_close)
{
extract_info (ce);
- e_card_simple_sync_card (ce->simple);
if (ce->book) {
EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
@@ -933,10 +959,10 @@ save_card (EContactEditor *ce, gboolean should_close)
gtk_widget_set_sensitive (ce->app, FALSE);
ce->in_async_call = TRUE;
- if (ce->is_new_card)
- e_card_merging_book_add_card (ce->book, ce->card, (EBookIdCallback)card_added_cb, ecs);
+ if (ce->is_new_contact)
+ eab_merging_book_add_contact (ce->book, ce->contact, (EBookIdCallback)contact_added_cb, ecs);
else
- e_card_merging_book_commit_card (ce->book, ce->card, (EBookCallback)card_modified_cb, ecs);
+ eab_merging_book_commit_contact (ce->book, ce->contact, (EBookCallback)contact_modified_cb, ecs);
}
}
@@ -957,9 +983,9 @@ prompt_to_save_changes (EContactEditor *editor)
if (!editor->changed)
return TRUE;
- switch (e_addressbook_prompt_save_dialog (GTK_WINDOW(editor->app))) {
+ switch (eab_prompt_save_dialog (GTK_WINDOW(editor->app))) {
case GTK_RESPONSE_YES:
- save_card (editor, FALSE);
+ save_contact (editor, FALSE);
return TRUE;
case GTK_RESPONSE_NO:
return TRUE;
@@ -978,7 +1004,7 @@ file_save_cb (GtkWidget *widget, gpointer data)
EContactEditor *ce;
ce = E_CONTACT_EDITOR (data);
- save_card (ce, FALSE);
+ save_contact (ce, FALSE);
}
/* File/Close callback */
@@ -998,45 +1024,38 @@ static void
file_save_as_cb (GtkWidget *widget, gpointer data)
{
EContactEditor *ce;
- ECard *card;
+ EContact *contact;
ce = E_CONTACT_EDITOR (data);
extract_info (ce);
- e_card_simple_sync_card (ce->simple);
- card = ce->card;
- e_contact_save_as(_("Save Contact as VCard"), card, GTK_WINDOW (ce->app));
+ contact = ce->contact;
+ eab_contact_save(_("Save Contact as VCard"), contact, GTK_WINDOW (ce->app));
}
static void
file_send_as_cb (GtkWidget *widget, gpointer data)
{
EContactEditor *ce;
- ECard *card;
ce = E_CONTACT_EDITOR (data);
extract_info (ce);
- e_card_simple_sync_card (ce->simple);
- card = ce->card;
- e_addressbook_send_card(card, E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT);
+ eab_send_contact(ce->contact, EAB_DISPOSITION_AS_ATTACHMENT);
}
static void
file_send_to_cb (GtkWidget *widget, gpointer data)
{
EContactEditor *ce;
- ECard *card;
ce = E_CONTACT_EDITOR (data);
extract_info (ce);
- e_card_simple_sync_card (ce->simple);
- card = ce->card;
- e_addressbook_send_card(card, E_ADDRESSBOOK_DISPOSITION_AS_TO);
+ eab_send_contact(ce->contact, EAB_DISPOSITION_AS_TO);
}
gboolean
@@ -1071,16 +1090,16 @@ e_contact_editor_confirm_delete (GtkWindow *parent)
}
static void
-card_deleted_cb (EBook *book, EBookStatus status, EContactEditor *ce)
+contact_deleted_cb (EBook *book, EBookStatus status, EContactEditor *ce)
{
gtk_widget_set_sensitive (ce->app, TRUE);
ce->in_async_call = FALSE;
- g_signal_emit (ce, contact_editor_signals[CARD_DELETED], 0,
- status, ce->card);
+ g_signal_emit (ce, contact_editor_signals[CONTACT_DELETED], 0,
+ status, ce->contact);
/* always close the dialog after we successfully delete a card */
- if (status == E_BOOK_STATUS_SUCCESS)
+ if (status == E_BOOK_ERROR_OK)
close_dialog (ce);
}
@@ -1088,27 +1107,23 @@ static void
delete_cb (GtkWidget *widget, gpointer data)
{
EContactEditor *ce = E_CONTACT_EDITOR (data);
- ECard *card = ce->card;
- ECardSimple *simple = ce->simple;
+ EContact *contact = ce->contact;
- g_object_ref(card);
- g_object_ref(simple);
+ g_object_ref(contact);
if (e_contact_editor_confirm_delete(GTK_WINDOW(ce->app))) {
extract_info (ce);
- e_card_simple_sync_card (simple);
- if (!ce->is_new_card && ce->book) {
+ if (!ce->is_new_contact && ce->book) {
gtk_widget_set_sensitive (ce->app, FALSE);
ce->in_async_call = TRUE;
- e_book_remove_card (ce->book, card, (EBookCallback)card_deleted_cb, ce);
+ e_book_async_remove_contact (ce->book, contact, (EBookCallback)contact_deleted_cb, ce);
}
}
- g_object_unref(card);
- g_object_unref(simple);
+ g_object_unref(contact);
}
/* Emits the signal to request printing a card */
@@ -1120,9 +1135,8 @@ print_cb (BonoboUIComponent *uih, void *data, const char *path)
ce = E_CONTACT_EDITOR (data);
extract_info (ce);
- e_card_simple_sync_card (ce->simple);
- gtk_widget_show(e_contact_print_card_dialog_new(ce->card));
+ gtk_widget_show(e_contact_print_contact_dialog_new(ce->contact));
}
#if 0 /* Envelope printing is disabled for Evolution 1.0. */
@@ -1148,7 +1162,7 @@ tb_save_and_close_cb (BonoboUIComponent *uih, void *data, const char *path)
EContactEditor *ce;
ce = E_CONTACT_EDITOR (data);
- save_card (ce, TRUE);
+ save_contact (ce, TRUE);
}
static
@@ -1244,6 +1258,7 @@ setup_tab_order(GladeXML *gui)
list = add_to_tab_order(list, gui, "entry-email1");
list = add_to_tab_order(list, gui, "alignment-htmlmail");
list = add_to_tab_order(list, gui, "entry-web");
+ list = add_to_tab_order(list, gui, "entry-blog");
list = add_to_tab_order(list, gui, "button-fulladdr");
list = add_to_tab_order(list, gui, "text-address");
list = g_list_reverse(list);
@@ -1271,22 +1286,20 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
e_contact_editor->email_list = NULL;
e_contact_editor->phone_list = NULL;
e_contact_editor->address_list = NULL;
- e_contact_editor->name = e_card_name_new();
+ e_contact_editor->name = e_contact_name_new();
e_contact_editor->company = g_strdup("");
- e_contact_editor->email_choice = 0;
- e_contact_editor->phone_choice[0] = E_CARD_SIMPLE_PHONE_ID_BUSINESS;
- e_contact_editor->phone_choice[1] = E_CARD_SIMPLE_PHONE_ID_HOME;
- e_contact_editor->phone_choice[2] = E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX;
- e_contact_editor->phone_choice[3] = E_CARD_SIMPLE_PHONE_ID_MOBILE;
+ e_contact_editor->email_choice = E_CONTACT_EMAIL_1;
+ e_contact_editor->phone_choice[0] = E_CONTACT_PHONE_BUSINESS;
+ e_contact_editor->phone_choice[1] = E_CONTACT_PHONE_HOME;
+ e_contact_editor->phone_choice[2] = E_CONTACT_PHONE_BUSINESS_FAX;
+ e_contact_editor->phone_choice[3] = E_CONTACT_PHONE_MOBILE;
+#if 0
e_contact_editor->address_choice = 0;
e_contact_editor->address_mailing = -1;
+#endif
- e_contact_editor->arbitrary_fields = NULL;
-
- e_contact_editor->simple = e_card_simple_new(NULL);
-
- e_contact_editor->card = NULL;
+ e_contact_editor->contact = NULL;
e_contact_editor->changed = FALSE;
e_contact_editor->in_async_call = FALSE;
e_contact_editor->editable = TRUE;
@@ -1298,10 +1311,6 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
e_contact_editor->app = glade_xml_get_widget (gui, "contact editor");
- e_container_foreach_leaf (GTK_CONTAINER (e_contact_editor->app),
- (GtkCallback) add_field_callback,
- e_contact_editor);
-
connect_arrow_button_signals(e_contact_editor);
set_entry_changed_signals(e_contact_editor);
@@ -1429,23 +1438,18 @@ e_contact_editor_dispose (GObject *object) {
e_contact_editor->address_popup = NULL;
}
- if (e_contact_editor->simple) {
- g_object_unref(e_contact_editor->simple);
- e_contact_editor->simple = NULL;
+ if (e_contact_editor->contact) {
+ g_object_unref(e_contact_editor->contact);
+ e_contact_editor->contact = NULL;
}
- if (e_contact_editor->card) {
- g_object_unref(e_contact_editor->card);
- e_contact_editor->card = NULL;
- }
-
if (e_contact_editor->book) {
g_object_unref(e_contact_editor->book);
e_contact_editor->book = NULL;
}
if (e_contact_editor->name) {
- e_card_name_unref(e_contact_editor->name);
+ e_contact_name_free(e_contact_editor->name);
e_contact_editor->name = NULL;
}
@@ -1474,7 +1478,7 @@ command_state_changed (EContactEditor *ce)
bonobo_ui_component_set_prop (ce->uic,
"/commands/ContactEditorDelete",
"sensitive",
- (ce->editable && !ce->is_new_card) ? "1" : "0", NULL);
+ (ce->editable && !ce->is_new_contact) ? "1" : "0", NULL);
}
static void
@@ -1506,14 +1510,14 @@ contact_editor_destroy_notify (void *data,
EContactEditor *
e_contact_editor_new (EBook *book,
- ECard *card,
- gboolean is_new_card,
+ EContact *contact,
+ gboolean is_new_contact,
gboolean editable)
{
EContactEditor *ce;
g_return_val_if_fail (E_IS_BOOK (book), NULL);
- g_return_val_if_fail (E_IS_CARD (card), NULL);
+ g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
ce = g_object_new (E_TYPE_CONTACT_EDITOR, NULL);
@@ -1525,13 +1529,13 @@ e_contact_editor_new (EBook *book,
g_object_set (ce,
"book", book,
- "card", card,
- "is_new_card", is_new_card,
+ "contact", contact,
+ "is_new_contact", is_new_contact,
"editable", editable,
NULL);
if (book)
- e_book_get_supported_fields (book, (EBookFieldsCallback)supported_fields_cb, ce);
+ e_book_async_get_supported_fields (book, (EBookFieldsCallback)supported_fields_cb, ce);
return ce;
}
@@ -1551,19 +1555,16 @@ e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *val
g_object_ref (editor->book);
/* XXX more here about editable/etc. */
break;
- case PROP_CARD:
- if (editor->card)
- g_object_unref(editor->card);
- editor->card = e_card_duplicate(E_CARD(g_value_get_object (value)));
- g_object_set(editor->simple,
- "card", editor->card,
- NULL);
+ case PROP_CONTACT:
+ if (editor->contact)
+ g_object_unref(editor->contact);
+ editor->contact = e_contact_duplicate(E_CONTACT(g_value_get_object (value)));
fill_in_info(editor);
editor->changed = FALSE;
break;
- case PROP_IS_NEW_CARD:
- editor->is_new_card = g_value_get_boolean (value) ? TRUE : FALSE;
+ case PROP_IS_NEW_CONTACT:
+ editor->is_new_contact = g_value_get_boolean (value) ? TRUE : FALSE;
break;
case PROP_EDITABLE: {
@@ -1617,14 +1618,13 @@ e_contact_editor_get_property (GObject *object, guint prop_id, GValue *value, GP
g_value_set_object (value, e_contact_editor->book);
break;
- case PROP_CARD:
- e_card_simple_sync_card(e_contact_editor->simple);
+ case PROP_CONTACT:
extract_info(e_contact_editor);
- g_value_set_object (value, e_contact_editor->card);
+ g_value_set_object (value, e_contact_editor->contact);
break;
- case PROP_IS_NEW_CARD:
- g_value_set_boolean (value, e_contact_editor->is_new_card ? TRUE : FALSE);
+ case PROP_IS_NEW_CONTACT:
+ g_value_set_boolean (value, e_contact_editor->is_new_contact ? TRUE : FALSE);
break;
case PROP_EDITABLE:
@@ -1730,33 +1730,11 @@ e_contact_editor_build_ui_info(GList *list, GnomeUIInfo **infop)
static void
e_contact_editor_build_phone_ui (EContactEditor *editor)
{
- int i;
-
if (editor->phone_list == NULL) {
- static char *info[] = {
- N_("Assistant"),
- N_("Business"),
- N_("Business 2"),
- N_("Business Fax"),
- N_("Callback"),
- N_("Car"),
- N_("Company"),
- N_("Home"),
- N_("Home 2"),
- N_("Home Fax"),
- N_("ISDN"),
- N_("Mobile"),
- N_("Other"),
- N_("Other Fax"),
- N_("Pager"),
- N_("Primary"),
- N_("Radio"),
- N_("Telex"),
- N_("TTY/TDD")
- };
-
- for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
- editor->phone_list = g_list_append(editor->phone_list, g_strdup(info[i]));
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (phones); i ++) {
+ editor->phone_list = g_list_append(editor->phone_list, g_strdup(e_contact_pretty_name (phones[i])));
}
}
if (editor->phone_info == NULL) {
@@ -1777,15 +1755,8 @@ e_contact_editor_build_email_ui (EContactEditor *editor)
int i;
if (editor->email_list == NULL) {
- static char *info[] = {
- N_("Primary Email"),
- N_("Email 2"),
- N_("Email 3")
- };
-
- for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
- editor->email_list = g_list_append(editor->email_list, g_strdup(info[i]));
- }
+ for (i = 0; i < G_N_ELEMENTS (emails); i++)
+ editor->email_list = g_list_append(editor->email_list, g_strdup(e_contact_pretty_name (emails[i])));
}
if (editor->email_info == NULL) {
e_contact_editor_build_ui_info(editor->email_list, &editor->email_info);
@@ -1851,21 +1822,21 @@ _phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor
e_contact_editor_build_phone_ui (editor);
- for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) {
- const ECardPhone *phone = e_card_simple_get_phone(editor->simple, i);
- gboolean checked;
- checked = phone && phone->number && *phone->number;
+ for(i = 0; i < G_N_ELEMENTS (phones); i++) {
+ char *phone = e_contact_get (editor->contact, phones[i]);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->phone_info[i].widget),
- checked);
+ phone && *phone);
+ g_free (phone);
}
result = _arrow_pressed (widget, button, editor, editor->phone_popup, &editor->phone_list, &editor->phone_info, label);
if (result != -1) {
- editor->phone_choice[which - 1] = result;
- set_fields(editor);
+ GtkWidget *w = glade_xml_get_widget (editor->gui, entry);
+ editor->phone_choice[which - 1] = phones[result];
+ set_fields (editor);
enable_widget (glade_xml_get_widget (editor->gui, label), TRUE);
- enable_widget (glade_xml_get_widget (editor->gui, entry), editor->editable);
+ enable_widget (w, editor->editable);
}
g_free(label);
@@ -1880,23 +1851,26 @@ _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor
e_contact_editor_build_email_ui (editor);
- for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) {
- const char *string = e_card_simple_get_email(editor->simple, i);
+ for(i = 0; i < G_N_ELEMENTS (emails); i++) {
+ char *string = e_contact_get (editor->contact, emails[i]);
gboolean checked;
checked = string && *string;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->email_info[i].widget),
checked);
+ g_free (string);
}
result = _arrow_pressed (widget, button, editor, editor->email_popup, &editor->email_list, &editor->email_info, "label-email1");
if (result != -1) {
+ GtkWidget *entry = glade_xml_get_widget (editor->gui, "entry-email1");
editor->email_choice = result;
- set_fields(editor);
+
+ set_fields (editor);
/* make sure the buttons/entry is/are sensitive */
enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), TRUE);
- enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), editor->editable);
+ enable_widget (entry, editor->editable);
enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), editor->editable);
}
}
@@ -1904,6 +1878,7 @@ _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor
static void
_address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
{
+#if notyet
int i;
int result;
@@ -1927,11 +1902,13 @@ _address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEdito
enable_widget (glade_xml_get_widget (editor->gui, "text-address"), editor->address_editable[result]);
enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-mailingaddress"), editor->address_editable[result]);
}
+#endif
}
static void
find_address_mailing (EContactEditor *editor)
{
+#if notyet
const ECardDeliveryAddress *address;
int i;
@@ -1951,6 +1928,7 @@ find_address_mailing (EContactEditor *editor)
}
}
}
+#endif
}
static void
@@ -1971,9 +1949,9 @@ set_field(EContactEditor *editor, GtkEntry *entry, const char *string)
}
static void
-set_phone_field(EContactEditor *editor, GtkWidget *entry, const ECardPhone *phone)
+set_phone_field(EContactEditor *editor, GtkWidget *entry, const char *phone_number)
{
- set_field(editor, GTK_ENTRY(entry), phone ? phone->number : "");
+ set_field(editor, GTK_ENTRY(entry), phone_number ? phone_number : "");
}
static void
@@ -1985,28 +1963,28 @@ set_fields(EContactEditor *editor)
entry = glade_xml_get_widget(editor->gui, "entry-phone1");
if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(editor, entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[0]));
+ set_phone_field(editor, entry, e_contact_get_const(editor->contact, editor->phone_choice[0]));
entry = glade_xml_get_widget(editor->gui, "entry-phone2");
if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(editor, entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[1]));
+ set_phone_field(editor, entry, e_contact_get_const(editor->contact, editor->phone_choice[1]));
entry = glade_xml_get_widget(editor->gui, "entry-phone3");
if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(editor, entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[2]));
+ set_phone_field(editor, entry, e_contact_get_const(editor->contact, editor->phone_choice[2]));
entry = glade_xml_get_widget(editor->gui, "entry-phone4");
if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(editor, entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[3]));
+ set_phone_field(editor, entry, e_contact_get_const(editor->contact, editor->phone_choice[3]));
entry = glade_xml_get_widget(editor->gui, "entry-email1");
if (entry && GTK_IS_ENTRY(entry))
- set_field(editor, GTK_ENTRY(entry), e_card_simple_get_email(editor->simple, editor->email_choice));
-
+ set_field(editor, GTK_ENTRY(entry), e_contact_get_const(editor->contact, editor->email_choice));
e_contact_editor_build_address_ui (editor);
+#if notyet
for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
const ECardAddrLabel *address = e_card_simple_get_address(editor->simple, i);
@@ -2024,11 +2002,13 @@ set_fields(EContactEditor *editor)
}
set_address_field(editor, i);
+#endif
}
static void
set_address_field(EContactEditor *editor, int result)
{
+#if notyet
GtkWidget *text, *check;
text = glade_xml_get_widget(editor->gui, "text-address");
@@ -2064,73 +2044,29 @@ set_address_field(EContactEditor *editor, int result)
editor->address_choice = result;
}
-}
-
-static void
-add_field_callback(GtkWidget *widget, EContactEditor *editor)
-{
- const char *name;
- int i;
- static const char *builtins[] = {
- "entry-fullname",
- "entry-web",
- "entry-company",
- "entry-department",
- "entry-office",
- "entry-jobtitle",
- "entry-profession",
- "entry-manager",
- "entry-assistant",
- "entry-nickname",
- "entry-spouse",
- "text-comments",
- "entry-categories",
- "entry-file-as",
- "dateedit-anniversary",
- "dateedit-birthday",
- "entry-phone1",
- "entry-phone2",
- "entry-phone3",
- "entry-phone4",
- "entry-email1",
- "text-address",
- "checkbutton-mailingaddress",
- "checkbutton-htmlmail",
- "entry-caluri",
- "entry-fburl",
- NULL
- };
- name = glade_get_widget_name(widget);
- if (name) {
- for (i = 0; builtins[i]; i++) {
- if (!strcmp(name, builtins[i]))
- return;
- }
- if (GTK_IS_ENTRY(widget) || GTK_IS_TEXT_VIEW(widget)) {
- editor->arbitrary_fields = g_list_prepend(editor->arbitrary_fields, g_strdup(name));
- }
- }
+#endif
}
static struct {
char *id;
- char *key;
+ EContactField field;
} field_mapping [] = {
- { "entry-fullname", "full_name" },
- { "entry-web", "url" },
- { "entry-company", "org" },
- { "entry-department", "org_unit" },
- { "entry-office", "office" },
- { "entry-jobtitle", "title" },
- { "entry-profession", "role" },
- { "entry-manager", "manager" },
- { "entry-assistant", "assistant" },
- { "entry-nickname", "nickname" },
- { "entry-spouse", "spouse" },
- { "text-comments", "note" },
- { "entry-categories", "categories" },
- { "entry-caluri", "caluri" },
- { "entry-fburl", "fburl" },
+ { "entry-fullname", E_CONTACT_FULL_NAME },
+ { "entry-web", E_CONTACT_HOMEPAGE_URL },
+ { "entry-blog", E_CONTACT_BLOG_URL },
+ { "entry-company", E_CONTACT_ORG },
+ { "entry-department", E_CONTACT_ORG_UNIT },
+ { "entry-office", E_CONTACT_OFFICE },
+ { "entry-jobtitle", E_CONTACT_TITLE },
+ { "entry-profession", E_CONTACT_ROLE },
+ { "entry-manager", E_CONTACT_MANAGER },
+ { "entry-assistant", E_CONTACT_ASSISTANT },
+ { "entry-nickname", E_CONTACT_NICKNAME },
+ { "entry-spouse", E_CONTACT_SPOUSE },
+ { "text-comments", E_CONTACT_NOTE },
+ { "entry-categories", E_CONTACT_CATEGORIES },
+ { "entry-caluri", E_CONTACT_CALENDAR_URI },
+ { "entry-fburl", E_CONTACT_FREEBUSY_URL },
};
static void
@@ -2159,36 +2095,6 @@ fill_in_field(EContactEditor *editor, char *id, char *value)
}
static void
-fill_in_card_field(EContactEditor *editor, ECard *card, char *id, char *key)
-{
- char *string;
- g_object_get (card,
- key, &string,
- NULL);
- fill_in_field(editor, id, string);
- g_free (string);
-}
-
-static void
-fill_in_single_field(EContactEditor *editor, char *name)
-{
- ECardSimple *simple = editor->simple;
- GtkWidget *widget = glade_xml_get_widget(editor->gui, name);
-
- if (widget && GTK_IS_EDITABLE(widget)) {
- int position = 0;
- GtkEditable *editable = GTK_EDITABLE(widget);
- const ECardArbitrary *arbitrary;
-
- gtk_editable_delete_text(editable, 0, -1);
- arbitrary = e_card_simple_get_arbitrary(simple,
- name);
- if (arbitrary && arbitrary->value)
- gtk_editable_insert_text(editable, arbitrary->value, strlen(arbitrary->value), &position);
- }
-}
-
-static void
disable_widget_foreach (char *key, GtkWidget *widget, gpointer closure)
{
enable_widget (widget, FALSE);
@@ -2196,62 +2102,65 @@ disable_widget_foreach (char *key, GtkWidget *widget, gpointer closure)
static struct {
char *widget_name;
- ECardSimpleField field_id;
+ EContactField field_id;
gboolean desensitize_for_read_only;
} widget_field_mappings[] = {
- { "entry-web", E_CARD_SIMPLE_FIELD_URL, TRUE },
- { "accellabel-web", E_CARD_SIMPLE_FIELD_URL },
+ { "entry-web", E_CONTACT_HOMEPAGE_URL, TRUE },
+ { "accellabel-web", E_CONTACT_HOMEPAGE_URL },
- { "entry-jobtitle", E_CARD_SIMPLE_FIELD_TITLE, TRUE },
- { "label-jobtitle", E_CARD_SIMPLE_FIELD_TITLE },
+ { "entry-blog", E_CONTACT_BLOG_URL, TRUE },
+ { "accellabel-blog", E_CONTACT_BLOG_URL },
- { "entry-company", E_CARD_SIMPLE_FIELD_ORG, TRUE },
- { "label-company", E_CARD_SIMPLE_FIELD_ORG },
+ { "entry-jobtitle", E_CONTACT_TITLE, TRUE },
+ { "label-jobtitle", E_CONTACT_TITLE },
- { "combo-file-as", E_CARD_SIMPLE_FIELD_FILE_AS, TRUE },
- { "entry-file-as", E_CARD_SIMPLE_FIELD_FILE_AS, TRUE },
- { "accellabel-fileas", E_CARD_SIMPLE_FIELD_FILE_AS },
+ { "entry-company", E_CONTACT_ORG, TRUE },
+ { "label-company", E_CONTACT_ORG },
- { "label-department", E_CARD_SIMPLE_FIELD_ORG_UNIT },
- { "entry-department", E_CARD_SIMPLE_FIELD_ORG_UNIT, TRUE },
+ { "combo-file-as", E_CONTACT_FILE_AS, TRUE },
+ { "entry-file-as", E_CONTACT_FILE_AS, TRUE },
+ { "accellabel-fileas", E_CONTACT_FILE_AS },
- { "label-office", E_CARD_SIMPLE_FIELD_OFFICE },
- { "entry-office", E_CARD_SIMPLE_FIELD_OFFICE, TRUE },
+ { "label-department", E_CONTACT_ORG_UNIT },
+ { "entry-department", E_CONTACT_ORG_UNIT, TRUE },
- { "label-profession", E_CARD_SIMPLE_FIELD_ROLE },
- { "entry-profession", E_CARD_SIMPLE_FIELD_ROLE, TRUE },
+ { "label-office", E_CONTACT_OFFICE },
+ { "entry-office", E_CONTACT_OFFICE, TRUE },
- { "label-manager", E_CARD_SIMPLE_FIELD_MANAGER },
- { "entry-manager", E_CARD_SIMPLE_FIELD_MANAGER, TRUE },
+ { "label-profession", E_CONTACT_ROLE },
+ { "entry-profession", E_CONTACT_ROLE, TRUE },
- { "label-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT },
- { "entry-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT, TRUE },
+ { "label-manager", E_CONTACT_MANAGER },
+ { "entry-manager", E_CONTACT_MANAGER, TRUE },
- { "label-nickname", E_CARD_SIMPLE_FIELD_NICKNAME },
- { "entry-nickname", E_CARD_SIMPLE_FIELD_NICKNAME, TRUE },
+ { "label-assistant", E_CONTACT_ASSISTANT },
+ { "entry-assistant", E_CONTACT_ASSISTANT, TRUE },
- { "label-spouse", E_CARD_SIMPLE_FIELD_SPOUSE },
- { "entry-spouse", E_CARD_SIMPLE_FIELD_SPOUSE, TRUE },
+ { "label-nickname", E_CONTACT_NICKNAME },
+ { "entry-nickname", E_CONTACT_NICKNAME, TRUE },
- { "label-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE },
- { "dateedit-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE, TRUE },
+ { "label-spouse", E_CONTACT_SPOUSE },
+ { "entry-spouse", E_CONTACT_SPOUSE, TRUE },
- { "label-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY },
- { "dateedit-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY, TRUE },
+ { "label-birthday", E_CONTACT_BIRTH_DATE },
+ { "dateedit-birthday", E_CONTACT_BIRTH_DATE, TRUE },
- { "label-comments", E_CARD_SIMPLE_FIELD_NOTE },
- { "text-comments", E_CARD_SIMPLE_FIELD_NOTE, TRUE },
+ { "label-anniversary", E_CONTACT_ANNIVERSARY },
+ { "dateedit-anniversary", E_CONTACT_ANNIVERSARY, TRUE },
- { "entry-fullname", E_CARD_SIMPLE_FIELD_FULL_NAME, TRUE },
+ { "label-comments", E_CONTACT_NOTE },
+ { "text-comments", E_CONTACT_NOTE, TRUE },
- { "button-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE },
- { "entry-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE },
+ { "entry-fullname", E_CONTACT_FULL_NAME, TRUE },
- { "label-caluri", E_CARD_SIMPLE_FIELD_CALURI },
- { "entry-caluri", E_CARD_SIMPLE_FIELD_CALURI, TRUE },
+ { "button-categories", E_CONTACT_CATEGORIES, TRUE },
+ { "entry-categories", E_CONTACT_CATEGORIES, TRUE },
- { "label-fburl", E_CARD_SIMPLE_FIELD_FBURL },
- { "entry-fburl", E_CARD_SIMPLE_FIELD_FBURL, TRUE }
+ { "label-caluri", E_CONTACT_CALENDAR_URI },
+ { "entry-caluri", E_CONTACT_CALENDAR_URI, TRUE },
+
+ { "label-fburl", E_CONTACT_FREEBUSY_URL },
+ { "entry-fburl", E_CONTACT_FREEBUSY_URL, TRUE }
};
static int num_widget_field_mappings = sizeof(widget_field_mappings) / sizeof (widget_field_mappings[0]);
@@ -2262,35 +2171,32 @@ enable_writable_fields(EContactEditor *editor)
EIterator *iter;
GHashTable *dropdown_hash, *supported_hash;
int i;
- ECardSimple *simple;
- ECard *card;
char *widget_name;
if (!fields)
return;
- card = e_card_new ("");
- simple = e_card_simple_new (card);
-
dropdown_hash = g_hash_table_new (g_str_hash, g_str_equal);
supported_hash = g_hash_table_new (g_str_hash, g_str_equal);
/* build our hashtable of the drop down menu items */
e_contact_editor_build_phone_ui (editor);
- for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++)
+ for (i = 0; i < G_N_ELEMENTS (phones); i ++)
g_hash_table_insert (dropdown_hash,
- (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_phone_to_field (i)),
+ (char*)e_contact_field_name(phones[i]),
editor->phone_info[i].widget);
e_contact_editor_build_email_ui (editor);
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++)
+ for (i = 0; i < G_N_ELEMENTS (emails); i ++)
g_hash_table_insert (dropdown_hash,
- (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_email_to_field (i)),
+ (char*)e_contact_field_name(phones[i]),
editor->email_info[i].widget);
+#if notyet
e_contact_editor_build_address_ui (editor);
for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++)
g_hash_table_insert (dropdown_hash,
(char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_address_to_field (i)),
editor->address_info[i].widget);
+#endif
/* then disable them all */
g_hash_table_foreach (dropdown_hash, (GHFunc)disable_widget_foreach, NULL);
@@ -2332,28 +2238,30 @@ enable_writable_fields(EContactEditor *editor)
g_hash_table_insert (supported_hash, field, field);
}
+#if notyet
for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) {
if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_address_to_field(i)))) {
editor->address_editable [i] = TRUE;
}
}
+#endif
/* ugh - this is needed to make sure we don't have a
disabled label next to a drop down when the item in
the menu (the one reflected in the label) is
enabled. */
- if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_email_to_field(editor->email_choice)))) {
+ if (!strcmp (field, e_contact_field_name (editor->email_choice))) {
enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), TRUE);
enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), editor->editable);
enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), editor->editable);
}
- else if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_address_to_field(editor->address_choice)))) {
+ else if (!strcmp (field, e_contact_field_name (editor->address_choice))) {
enable_widget (glade_xml_get_widget (editor->gui, "label-address"), TRUE);
enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-mailingaddress"), editor->editable);
enable_widget (glade_xml_get_widget (editor->gui, "text-address"), editor->editable);
}
else for (i = 0; i < 4; i ++) {
- if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_phone_to_field(editor->phone_choice[i])))) {
+ if (!strcmp (field, e_contact_field_name (editor->phone_choice[i]))) {
widget_name = g_strdup_printf ("label-phone%d", i+1);
enable_widget (glade_xml_get_widget (editor->gui, widget_name), TRUE);
g_free (widget_name);
@@ -2377,8 +2285,7 @@ enable_writable_fields(EContactEditor *editor)
widget_field_mappings[i].widget_name);
continue;
}
- field = e_card_simple_get_ecard_field (simple,
- widget_field_mappings[i].field_id);
+ field = e_contact_field_name (widget_field_mappings[i].field_id);
enabled = (g_hash_table_lookup (supported_hash, field) != NULL);
@@ -2393,8 +2300,6 @@ enable_writable_fields(EContactEditor *editor)
g_hash_table_destroy (dropdown_hash);
g_hash_table_destroy (supported_hash);
- g_object_unref (simple);
- g_object_unref (card);
}
static void
@@ -2436,51 +2341,46 @@ set_editable (EContactEditor *editor)
static void
fill_in_info(EContactEditor *editor)
{
- ECard *card = editor->card;
- if (card) {
+ EContact *contact = editor->contact;
+ if (contact) {
char *file_as;
- ECardName *name;
- const ECardDate *anniversary;
- const ECardDate *bday;
+ EContactName *name;
+ EContactDate *anniversary;
+ EContactDate *bday;
int i;
GtkWidget *widget;
- GList *list;
- gboolean wants_html, wants_html_set;
-
- g_object_get (card,
- "file_as", &file_as,
- "name", &name,
- "anniversary", &anniversary,
- "birth_date", &bday,
- "wants_html_set", &wants_html_set,
- "wants_html", &wants_html,
- NULL);
-
- for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) {
- fill_in_card_field(editor, card, field_mapping[i].id, field_mapping[i].key);
- }
+ gboolean wants_html;
+
+ g_object_get (contact,
+ "file_as", &file_as,
+ "name", &name,
+ "anniversary", &anniversary,
+ "birth_date", &bday,
+ "wants_html", &wants_html,
+ NULL);
- for (list = editor->arbitrary_fields; list; list = list->next) {
- fill_in_single_field(editor, list->data);
+ for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) {
+ char *string = e_contact_get (contact, field_mapping[i].field);
+ fill_in_field(editor, field_mapping[i].id, string);
+ g_free (string);
}
find_address_mailing (editor);
- if (wants_html_set) {
- GtkWidget *widget = glade_xml_get_widget(editor->gui, "checkbutton-htmlmail");
- if (widget && GTK_IS_CHECK_BUTTON(widget)) {
- g_object_set (widget,
- "active", wants_html,
- NULL);
- }
+ widget = glade_xml_get_widget(editor->gui, "checkbutton-htmlmail");
+ if (widget && GTK_IS_CHECK_BUTTON(widget)) {
+ g_object_set (widget,
+ "active", wants_html,
+ NULL);
}
/* File as has to come after company and name or else it'll get messed up when setting them. */
fill_in_field(editor, "entry-file-as", file_as);
- g_free (file_as);
- e_card_name_unref(editor->name);
- editor->name = e_card_name_ref(name);
+ g_free (file_as);
+ if (editor->name)
+ e_contact_name_free(editor->name);
+ editor->name = name;
widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary");
if (widget && E_IS_DATE_EDIT(widget)) {
@@ -2508,12 +2408,15 @@ fill_in_info(EContactEditor *editor)
e_date_edit_set_time (dateedit, -1);
}
+ e_contact_date_free (anniversary);
+ e_contact_date_free (bday);
+
set_fields(editor);
}
}
static void
-extract_field(EContactEditor *editor, ECard *card, char *editable_id, char *key)
+extract_field(EContactEditor *editor, EContact *contact, char *editable_id, EContactField field)
{
GtkWidget *widget = glade_xml_get_widget(editor->gui, editable_id);
char *string = NULL;
@@ -2538,50 +2441,22 @@ extract_field(EContactEditor *editor, ECard *card, char *editable_id, char *key)
}
if (string && *string)
- g_object_set (card,
- key, string,
- NULL);
+ e_contact_set (contact, field, string);
else
- g_object_set (card,
- key, NULL,
- NULL);
+ e_contact_set (contact, field, NULL);
if (string) g_free(string);
}
static void
-extract_single_field(EContactEditor *editor, char *name)
-{
- GtkWidget *widget = glade_xml_get_widget(editor->gui, name);
- ECardSimple *simple = editor->simple;
- if (widget && GTK_IS_EDITABLE(widget)) {
- GtkEditable *editable = GTK_EDITABLE(widget);
- char *string = gtk_editable_get_chars(editable, 0, -1);
-
- if (string && *string)
- e_card_simple_set_arbitrary(simple,
- name,
- NULL,
- string);
- else
- e_card_simple_set_arbitrary(simple,
- name,
- NULL,
- NULL);
- if (string) g_free(string);
- }
-}
-
-static void
extract_info(EContactEditor *editor)
{
- ECard *card = editor->card;
- if (card) {
- ECardDate anniversary;
- ECardDate bday;
+ EContact *contact = editor->contact;
+ if (contact) {
+ EContactDate anniversary;
+ EContactDate bday;
int i;
GtkWidget *widget;
- GList *list;
widget = glade_xml_get_widget(editor->gui, "entry-file-as");
if (widget && GTK_IS_EDITABLE(widget)) {
@@ -2589,25 +2464,17 @@ extract_info(EContactEditor *editor)
char *string = gtk_editable_get_chars(editable, 0, -1);
if (string && *string)
- g_object_set (card,
- "file_as", string,
- NULL);
+ e_contact_set (contact, E_CONTACT_FILE_AS, string);
- if (string) g_free(string);
+ g_free(string);
}
for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) {
- extract_field(editor, card, field_mapping[i].id, field_mapping[i].key);
- }
-
- for (list = editor->arbitrary_fields; list; list = list->next) {
- extract_single_field(editor, list->data);
+ extract_field(editor, contact, field_mapping[i].id, field_mapping[i].field);
}
if (editor->name)
- g_object_set (card,
- "name", editor->name,
- NULL);
+ e_contact_set (contact, E_CONTACT_NAME, editor->name);
widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary");
if (widget && E_IS_DATE_EDIT(widget)) {
@@ -2616,13 +2483,9 @@ extract_info(EContactEditor *editor)
&anniversary.month,
&anniversary.day)) {
/* g_print ("%d %d %d\n", anniversary.year, anniversary.month, anniversary.day); */
- g_object_set (card,
- "anniversary", &anniversary,
- NULL);
+ e_contact_set (contact, E_CONTACT_ANNIVERSARY, &anniversary);
} else
- g_object_set (card,
- "anniversary", NULL,
- NULL);
+ e_contact_set (contact, E_CONTACT_ANNIVERSARY, NULL);
}
widget = glade_xml_get_widget(editor->gui, "dateedit-birthday");
@@ -2632,13 +2495,9 @@ extract_info(EContactEditor *editor)
&bday.month,
&bday.day)) {
/* g_print ("%d %d %d\n", bday.year, bday.month, bday.day); */
- g_object_set (card,
- "birth_date", &bday,
- NULL);
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, &bday);
} else
- g_object_set (card,
- "birth_date", NULL,
- NULL);
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, NULL);
}
}
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index 8642aecac1..efee496539 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -25,9 +25,8 @@
#include <bonobo/bonobo-ui-component.h>
#include <glade/glade.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include "addressbook/backend/ebook/e-book-async.h"
+#include "addressbook/backend/ebook/e-contact.h"
G_BEGIN_DECLS
@@ -56,8 +55,7 @@ struct _EContactEditor
/* item specific fields */
EBook *book;
- ECard *card;
- ECardSimple *simple;
+ EContact *contact;
/* UI handler */
BonoboUIComponent *uic;
@@ -74,20 +72,18 @@ struct _EContactEditor
GList *phone_list;
GList *address_list;
- ECardName *name;
+ EContactName *name;
char *company;
- ECardSimpleEmailId email_choice;
- ECardSimplePhoneId phone_choice[4];
- ECardSimpleAddressId address_choice;
- ECardSimpleAddressId address_mailing;
+ EContactField email_choice;
+ EContactField phone_choice[4];
+ EContactField address_choice;
+ EContactField address_mailing;
- GList *arbitrary_fields;
+ /* Whether we are editing a new contact or an existing one */
+ guint is_new_contact : 1;
- /* Whether we are editing a new card or an existing one */
- guint is_new_card : 1;
-
- /* Whether the card has been changed since bringing up the contact editor */
+ /* Whether the contact has been changed since bringing up the contact editor */
guint changed : 1;
/* Whether the contact editor will accept modifications */
@@ -96,8 +92,10 @@ struct _EContactEditor
/* Whether the fullname will accept modifications */
guint fullname_editable : 1;
+#if notyet
/* Whether each of the addresses are editable */
gboolean address_editable[E_CARD_SIMPLE_ADDRESS_ID_LAST];
+#endif
/* Whether an async wombat call is in progress */
guint in_async_call : 1;
@@ -111,15 +109,15 @@ struct _EContactEditorClass
/* Notification signals */
- void (* card_added) (EContactEditor *ce, EBookStatus status, ECard *card);
- void (* card_modified) (EContactEditor *ce, EBookStatus status, ECard *card);
- void (* card_deleted) (EContactEditor *ce, EBookStatus status, ECard *card);
- void (* editor_closed) (EContactEditor *ce);
+ void (* contact_added) (EContactEditor *ce, EBookStatus status, EContact *contact);
+ void (* contact_modified) (EContactEditor *ce, EBookStatus status, EContact *contact);
+ void (* contact_deleted) (EContactEditor *ce, EBookStatus status, EContact *contact);
+ void (* editor_closed) (EContactEditor *ce);
};
EContactEditor *e_contact_editor_new (EBook *book,
- ECard *card,
- gboolean is_new_card,
+ EContact *contact,
+ gboolean is_new_contact,
gboolean editable);
GType e_contact_editor_get_type (void);
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c
index 703996ee07..65b321c997 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.c
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.c
@@ -37,17 +37,17 @@
#include <libgnomeui/gnome-app.h>
#include <addressbook/gui/component/addressbook.h>
#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
+#include <addressbook/util/eab-book-util.h>
+#include <addressbook/backend/ebook/e-contact.h>
#include "e-contact-editor.h"
#include "e-contact-quick-add.h"
-#include "e-card-merging.h"
+#include "eab-contact-merging.h"
typedef struct _QuickAdd QuickAdd;
struct _QuickAdd {
gchar *name;
gchar *email;
- ECard *card;
+ EContact *contact;
EContactQuickAddCallback cb;
gpointer closure;
@@ -63,7 +63,7 @@ static QuickAdd *
quick_add_new (void)
{
QuickAdd *qa = g_new0 (QuickAdd, 1);
- qa->card = e_card_new ("");
+ qa->contact = e_contact_new ();
qa->refs = 1;
return qa;
}
@@ -84,7 +84,7 @@ quick_add_unref (QuickAdd *qa)
if (qa->refs == 0) {
g_free (qa->name);
g_free (qa->email);
- g_object_unref (qa->card);
+ g_object_unref (qa->contact);
g_free (qa);
}
}
@@ -93,7 +93,8 @@ quick_add_unref (QuickAdd *qa)
static void
quick_add_set_name (QuickAdd *qa, const gchar *name)
{
- ECardName *card_name;
+#if notyet
+ EContactName *card_name;
if (name == qa->name)
return;
@@ -108,23 +109,19 @@ quick_add_set_name (QuickAdd *qa, const gchar *name)
NULL);
e_card_name_unref (card_name);
+#endif
}
static void
quick_add_set_email (QuickAdd *qa, const gchar *email)
{
- ECardSimple *simple;
-
if (email == qa->email)
return;
g_free (qa->email);
qa->email = g_strdup (email);
- simple = e_card_simple_new (qa->card);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, email);
- e_card_simple_sync_card (simple);
- g_object_unref (simple);
+ e_contact_set (qa->contact, E_CONTACT_EMAIL_1, (char*)email);
}
static void
@@ -132,10 +129,10 @@ merge_cb (EBook *book, EBookStatus status, gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
- if (status == E_BOOK_STATUS_SUCCESS) {
- e_card_merging_book_add_card (book, qa->card, NULL, NULL);
+ if (status == E_BOOK_ERROR_OK) {
+ eab_merging_book_add_contact (book, qa->contact, NULL, NULL);
if (qa->cb)
- qa->cb (qa->card, qa->closure);
+ qa->cb (qa->contact, qa->closure);
g_object_unref (book);
} else {
/* Something went wrong. */
@@ -149,14 +146,11 @@ merge_cb (EBook *book, EBookStatus status, gpointer closure)
}
static void
-quick_add_merge_card (QuickAdd *qa)
+quick_add_merge_contact (QuickAdd *qa)
{
- EBook *book;
-
quick_add_ref (qa);
- book = e_book_new ();
- addressbook_load_default_book (book, merge_cb, qa);
+ addressbook_load_default_book (merge_cb, qa);
}
@@ -165,14 +159,14 @@ quick_add_merge_card (QuickAdd *qa)
*/
static void
-card_added_cb (EContactEditor *ce, EBookStatus status, ECard *card, gpointer closure)
+contact_added_cb (EContactEditor *ce, EBookStatus status, EContact *contact, gpointer closure)
{
QuickAdd *qa = (QuickAdd *) g_object_get_data (G_OBJECT (ce), "quick_add");
if (qa) {
if (qa->cb)
- qa->cb (qa->card, qa->closure);
+ qa->cb (qa->contact, qa->closure);
/* We don't need to unref qa because we set_data_full below */
g_object_set_data (G_OBJECT (ce), "quick_add", NULL);
@@ -196,13 +190,13 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
- if (status != E_BOOK_STATUS_SUCCESS) {
+ if (status != E_BOOK_ERROR_OK) {
if (book)
g_object_unref (book);
g_warning ("Couldn't open local address book.");
quick_add_unref (qa);
} else {
- EContactEditor *contact_editor = e_contact_editor_new (book, qa->card, TRUE, TRUE /* XXX */);
+ EContactEditor *contact_editor = e_contact_editor_new (book, qa->contact, TRUE, TRUE /* XXX */);
/* mark it as changed so the Save buttons are enabled when we bring up the dialog. */
g_object_set (contact_editor,
@@ -210,14 +204,14 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
NULL);
/* We pass this via object data, so that we don't get a dangling pointer referenced if both
- the "card_added" and "editor_closed" get emitted. (Which, based on a backtrace in bugzilla,
+ the "contact_added" and "editor_closed" get emitted. (Which, based on a backtrace in bugzilla,
I think can happen and cause a crash. */
g_object_set_data_full (G_OBJECT (contact_editor), "quick_add", qa,
(GDestroyNotify) quick_add_unref);
g_signal_connect (contact_editor,
- "card_added",
- G_CALLBACK (card_added_cb),
+ "contact_added",
+ G_CALLBACK (contact_added_cb),
NULL);
g_signal_connect (contact_editor,
"editor_closed",
@@ -229,11 +223,9 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
}
static void
-edit_card (QuickAdd *qa)
+edit_contact (QuickAdd *qa)
{
- EBook *book;
- book = e_book_new ();
- addressbook_load_default_book (book, ce_have_book, qa);
+ addressbook_load_default_book (ce_have_book, qa);
}
#define QUICK_ADD_RESPONSE_EDIT_FULL 2
@@ -272,12 +264,12 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure)
if (button == GTK_RESPONSE_OK) {
/* OK */
- quick_add_merge_card (qa);
+ quick_add_merge_contact (qa);
} else if (button == QUICK_ADD_RESPONSE_EDIT_FULL) {
/* EDIT FULL */
- edit_card (qa);
+ edit_contact (qa);
} else {
/* CANCEL */
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.h b/addressbook/gui/contact-editor/e-contact-quick-add.h
index 1bf69ee114..ad98c73c23 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.h
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.h
@@ -27,9 +27,9 @@
#ifndef __E_CONTACT_QUICK_ADD_H__
#define __E_CONTACT_QUICK_ADD_H__
-#include <addressbook/backend/ebook/e-card.h>
+#include <addressbook/backend/ebook/e-contact.h>
-typedef void (*EContactQuickAddCallback) (ECard *new_card, gpointer closure);
+typedef void (*EContactQuickAddCallback) (EContact *new_contact, gpointer closure);
void e_contact_quick_add (const gchar *name, const gchar *email,
EContactQuickAddCallback cb, gpointer closure);
diff --git a/addressbook/gui/contact-editor/e-contact-save-as.c b/addressbook/gui/contact-editor/e-contact-save-as.c
deleted file mode 100644
index a141560763..0000000000
--- a/addressbook/gui/contact-editor/e-contact-save-as.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-editor.h
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include "e-contact-save-as.h"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <gtk/gtkfilesel.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkmessagedialog.h>
-#include <gal/util/e-util.h>
-#include <libgnome/gnome-i18n.h>
-#include <errno.h>
-#include <string.h>
-#include <libgnomeui/gnome-messagebox.h>
-
-static gint file_exists(GtkFileSelection *filesel, const char *filename);
-
-typedef struct {
- GtkFileSelection *filesel;
- char *vcard;
-} SaveAsInfo;
-
-static void
-save_it(GtkWidget *widget, SaveAsInfo *info)
-{
- gint error = 0;
- gint response = 0;
-
- const char *filename = gtk_file_selection_get_filename (info->filesel);
-
- error = e_write_file (filename, info->vcard, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC);
-
- if (error == EEXIST) {
- response = file_exists(info->filesel, filename);
- switch (response) {
- case GTK_RESPONSE_ACCEPT : /* Overwrite */
- e_write_file(filename, info->vcard, O_WRONLY | O_CREAT | O_TRUNC);
- break;
- case GTK_RESPONSE_REJECT : /* cancel */
- return;
- }
- } else if (error != 0) {
- GtkWidget *dialog;
- char *str;
-
- str = g_strdup_printf (_("Error saving %s: %s"), filename, strerror(errno));
- dialog = gtk_message_dialog_new (GTK_WINDOW (info->filesel),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- str);
- g_free (str);
-
- gtk_widget_show (dialog);
-
- return;
- }
-
- gtk_widget_destroy(GTK_WIDGET(info->filesel));
-}
-
-static void
-close_it(GtkWidget *widget, SaveAsInfo *info)
-{
- gtk_widget_destroy (GTK_WIDGET (info->filesel));
-}
-
-static void
-destroy_it(void *data, GObject *where_the_object_was)
-{
- SaveAsInfo *info = data;
- g_free (info->vcard);
- g_free (info);
-}
-
-static char *
-make_safe_filename (const char *prefix, char *name)
-{
- char *safe, *p;
-
- if (!name) {
- /* This is a filename. Translators take note. */
- name = _("card.vcf");
- }
-
- p = strrchr (name, '/');
- if (p)
- safe = g_strdup_printf ("%s%s%s", prefix, p, ".vcf");
- else
- safe = g_strdup_printf ("%s/%s%s", prefix, name, ".vcf");
-
- p = strrchr (safe, '/') + 1;
- if (p)
- e_filename_make_safe (p);
-
- return safe;
-}
-
-void
-e_contact_save_as(char *title, ECard *card, GtkWindow *parent_window)
-{
- GtkFileSelection *filesel;
- char *file;
- char *name;
- SaveAsInfo *info = g_new(SaveAsInfo, 1);
-
- filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title));
-
- g_object_get (card,
- "file_as", &name,
- NULL);
- file = make_safe_filename (g_get_home_dir(), name);
- gtk_file_selection_set_filename (filesel, file);
- g_free (file);
- g_free (name);
-
- info->filesel = filesel;
- info->vcard = e_card_get_vcard(card);
-
- g_signal_connect(filesel->ok_button, "clicked",
- G_CALLBACK (save_it), info);
- g_signal_connect(filesel->cancel_button, "clicked",
- G_CALLBACK (close_it), info);
- g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
-
- if (parent_window) {
- gtk_window_set_transient_for (GTK_WINDOW (filesel),
- parent_window);
- gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
- }
-
- gtk_widget_show(GTK_WIDGET(filesel));
-}
-
-void
-e_contact_list_save_as(char *title, GList *list, GtkWindow *parent_window)
-{
- GtkFileSelection *filesel;
- SaveAsInfo *info = g_new(SaveAsInfo, 1);
-
- filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title));
-
- /* This is a filename. Translators take note. */
- if (list && list->data && list->next == NULL) {
- char *name, *file;
- g_object_get (list->data,
- "file_as", &name,
- NULL);
- file = make_safe_filename (g_get_home_dir(), name);
- gtk_file_selection_set_filename (filesel, file);
- g_free (file);
- g_free (name);
- } else {
- char *file;
- file = make_safe_filename (g_get_home_dir(), _("list"));
- gtk_file_selection_set_filename (filesel, file);
- g_free (file);
- }
-
- info->filesel = filesel;
- info->vcard = e_card_list_get_vcard (list);
-
- g_signal_connect(filesel->ok_button, "clicked",
- G_CALLBACK (save_it), info);
- g_signal_connect(filesel->cancel_button, "clicked",
- G_CALLBACK (close_it), info);
- g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
-
- if (parent_window) {
- gtk_window_set_transient_for (GTK_WINDOW (filesel),
- parent_window);
- gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
- }
-
- gtk_widget_show(GTK_WIDGET(filesel));
-}
-
-static gint
-file_exists(GtkFileSelection *filesel, const char *filename)
-{
- GtkWidget *dialog;
- gint response;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (filesel),
- 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- _("%s already exists\nDo you want to overwrite it?"), filename);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
- _("Overwrite"), GTK_RESPONSE_ACCEPT,
- NULL);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return response;
-}
diff --git a/addressbook/gui/contact-editor/e-contact-save-as.h b/addressbook/gui/contact-editor/e-contact-save-as.h
deleted file mode 100644
index 2b01ad8435..0000000000
--- a/addressbook/gui/contact-editor/e-contact-save-as.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-save-as.h
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __E_CONTACT_SAVE_AS_H__
-#define __E_CONTACT_SAVE_AS_H__
-
-#include <gtk/gtkwindow.h>
-#include <glade/glade.h>
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-void e_contact_save_as (gchar *title, ECard *card, GtkWindow *parent_window);
-void e_contact_list_save_as (gchar *title, GList *list, GtkWindow *parent_window);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_CONTACT_EDITOR_H__ */
diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.glade b/addressbook/gui/contact-list-editor/contact-list-editor.glade
index c64eebd520..002e697105 100644
--- a/addressbook/gui/contact-list-editor/contact-list-editor.glade
+++ b/addressbook/gui/contact-list-editor/contact-list-editor.glade
@@ -78,7 +78,7 @@
</child>
<child>
- <widget class="Custom" id="custom7">
+ <widget class="Custom" id="list-image">
<property name="visible">True</property>
<property name="creation_function">e_create_image_widget</property>
<property name="string1">evolution-contacts-plain.png</property>
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index 39f251f5ee..a475d15cd6 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -30,12 +30,13 @@
#include <bonobo/bonobo-ui-util.h>
#include <bonobo/bonobo-window.h>
#include <gal/e-table/e-table-scrolled.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
#include "shell/evolution-shell-component-utils.h"
-#include "addressbook/gui/widgets/e-addressbook-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+#include "addressbook/util/eab-book-util.h"
#include "e-contact-editor.h"
-#include "e-contact-save-as.h"
#include "e-contact-list-model.h"
#include "e-contact-list-editor-marshal.h"
@@ -76,6 +77,17 @@ static void table_drag_data_received_cb (ETable *table, int row, int col,
gint x, gint y,
GtkSelectionData *selection_data, guint info, guint time,
EContactListEditor *editor);
+static gboolean image_drag_motion_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y, guint time, EContactListEditor *editor);
+static gboolean image_drag_drop_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y, guint time, EContactListEditor *editor);
+static void image_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time, EContactListEditor *editor);
static GtkObjectClass *parent_class = NULL;
@@ -83,18 +95,26 @@ static guint contact_list_editor_signals[LAST_SIGNAL];
enum DndTargetType {
DND_TARGET_TYPE_VCARD,
+ DND_TARGET_TYPE_URI_LIST
};
#define VCARD_TYPE "text/x-vcard"
-static GtkTargetEntry drag_types[] = {
+#define URI_LIST_TYPE "text/uri-list"
+
+static GtkTargetEntry list_drag_types[] = {
{ VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
};
-static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
+static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
+
+static GtkTargetEntry image_drag_types[] = {
+ { URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST },
+};
+static const int num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]);
/* The arguments we take */
enum {
PROP_0,
PROP_BOOK,
- PROP_CARD,
+ PROP_CONTACT,
PROP_IS_NEW_LIST,
PROP_EDITABLE
};
@@ -144,11 +164,11 @@ e_contact_list_editor_class_init (EContactListEditorClass *klass)
E_TYPE_BOOK,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class, PROP_CARD,
- g_param_spec_object ("card",
- _("Card"),
+ g_object_class_install_property (object_class, PROP_CONTACT,
+ g_param_spec_object ("contact",
+ _("Contact"),
/*_( */"XXX blurb" /*)*/,
- E_TYPE_CARD,
+ E_TYPE_CONTACT,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_IS_NEW_LIST,
@@ -212,8 +232,10 @@ e_contact_list_editor_init (EContactListEditor *editor)
GtkWidget *bonobo_win;
BonoboUIContainer *container;
char *icon_path;
+ GdkPixbuf *pixbuf;
- editor->card = NULL;
+ editor->image_buf = NULL;
+ editor->contact = NULL;
editor->changed = FALSE;
editor->editable = TRUE;
editor->in_async_call = FALSE;
@@ -235,9 +257,17 @@ e_contact_list_editor_init (EContactListEditor *editor)
editor->email_entry = glade_xml_get_widget (gui, "email-entry");
editor->list_name_entry = glade_xml_get_widget (gui, "list-name-entry");
-
+ editor->list_image = glade_xml_get_widget (gui, "list-image");
+ if (GTK_IS_ALIGNMENT (editor->list_image)) {
+ /* deal with the e_create_image_widget code, that wraps the image in an alignment */
+ editor->list_image = GTK_BIN (editor->list_image)->child;
+ }
editor->visible_addrs_checkbutton = glade_xml_get_widget (gui, "visible-addrs-checkbutton");
+ pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (editor->list_image));
+ editor->list_image_width = gdk_pixbuf_get_width (pixbuf);
+ editor->list_image_height = gdk_pixbuf_get_height (pixbuf);
+
/* Construct the app */
bonobo_win = bonobo_window_new ("contact-list-editor", _("Contact List Editor"));
@@ -286,7 +316,7 @@ e_contact_list_editor_init (EContactListEditor *editor)
"toggled", G_CALLBACK(visible_addrs_toggled_cb), editor);
e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- 0, drag_types, num_drag_types, GDK_ACTION_LINK);
+ 0, list_drag_types, num_list_drag_types, GDK_ACTION_LINK);
g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
"table_drag_motion", G_CALLBACK(table_drag_motion_cb), editor);
@@ -295,6 +325,14 @@ e_contact_list_editor_init (EContactListEditor *editor)
g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
"table_drag_data_received", G_CALLBACK(table_drag_data_received_cb), editor);
+ gtk_drag_dest_set (editor->list_image, 0, image_drag_types, num_image_drag_types, GDK_ACTION_COPY);
+ g_signal_connect (editor->list_image,
+ "drag_motion", G_CALLBACK (image_drag_motion_cb), editor);
+ g_signal_connect (editor->list_image,
+ "drag_drop", G_CALLBACK (image_drag_drop_cb), editor);
+ g_signal_connect (editor->list_image,
+ "drag_data_received", G_CALLBACK (image_drag_data_received_cb), editor);
+
command_state_changed (editor);
/* Connect to the deletion of the dialog */
@@ -311,6 +349,13 @@ e_contact_list_editor_init (EContactListEditor *editor)
static void
e_contact_list_editor_dispose (GObject *object)
{
+ EContactListEditor *cle = E_CONTACT_LIST_EDITOR (object);
+
+ if (cle->image_buf) {
+ g_free (cle->image_buf);
+ cle->image_buf = NULL;
+ }
+
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
@@ -330,12 +375,12 @@ list_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruc
gtk_widget_set_sensitive (cle->app, TRUE);
cle->in_async_call = FALSE;
- e_card_set_id (cle->card, id);
+ e_contact_set (cle->contact, E_CONTACT_UID, (char*)id);
g_signal_emit (cle, contact_list_editor_signals[LIST_ADDED], 0,
- status, cle->card);
+ status, cle->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
cle->is_new_list = FALSE;
if (should_close)
@@ -359,9 +404,9 @@ list_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
cle->in_async_call = FALSE;
g_signal_emit (cle, contact_list_editor_signals[LIST_MODIFIED], 0,
- status, cle->card);
+ status, cle->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
if (should_close)
close_dialog (cle);
}
@@ -371,7 +416,7 @@ list_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
}
static void
-save_card (EContactListEditor *cle, gboolean should_close)
+save_contact (EContactListEditor *cle, gboolean should_close)
{
extract_info (cle);
@@ -387,9 +432,9 @@ save_card (EContactListEditor *cle, gboolean should_close)
cle->in_async_call = TRUE;
if (cle->is_new_list)
- e_book_add_card (cle->book, cle->card, (EBookIdCallback)list_added_cb, ecs);
+ e_book_async_add_contact (cle->book, cle->contact, (EBookIdCallback)list_added_cb, ecs);
else
- e_book_commit_card (cle->book, cle->card, (EBookCallback)list_modified_cb, ecs);
+ e_book_async_commit_contact (cle->book, cle->contact, (EBookCallback)list_modified_cb, ecs);
cle->changed = FALSE;
}
@@ -416,9 +461,9 @@ prompt_to_save_changes (EContactListEditor *editor)
if (!editor->changed || !is_named (editor))
return TRUE;
- switch (e_addressbook_prompt_save_dialog (GTK_WINDOW(editor->app))) {
+ switch (eab_prompt_save_dialog (GTK_WINDOW(editor->app))) {
case GTK_RESPONSE_YES:
- save_card (editor, FALSE);
+ save_contact (editor, FALSE);
return TRUE;
case GTK_RESPONSE_NO:
return TRUE;
@@ -444,7 +489,7 @@ file_save_cb (GtkWidget *widget, gpointer data)
{
EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
- save_card (cle, FALSE);
+ save_contact (cle, FALSE);
}
static void
@@ -454,7 +499,7 @@ file_save_as_cb (GtkWidget *widget, gpointer data)
extract_info (cle);
- e_contact_save_as(_("Save List as VCard"), cle->card, GTK_WINDOW (cle->app));
+ eab_contact_save(_("Save List as VCard"), cle->contact, GTK_WINDOW (cle->app));
}
static void
@@ -464,7 +509,7 @@ file_send_as_cb (GtkWidget *widget, gpointer data)
extract_info (cle);
- e_addressbook_send_card(cle->card, E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT);
+ eab_send_contact(cle->contact, EAB_DISPOSITION_AS_ATTACHMENT);
}
static void
@@ -474,14 +519,14 @@ file_send_to_cb (GtkWidget *widget, gpointer data)
extract_info (cle);
- e_addressbook_send_card(cle->card, E_ADDRESSBOOK_DISPOSITION_AS_TO);
+ eab_send_contact(cle->contact, EAB_DISPOSITION_AS_TO);
}
static void
tb_save_and_close_cb (GtkWidget *widget, gpointer data)
{
EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
- save_card (cle, TRUE);
+ save_contact (cle, TRUE);
}
static void
@@ -492,10 +537,10 @@ list_deleted_cb (EBook *book, EBookStatus status, EContactListEditor *cle)
cle->in_async_call = FALSE;
g_signal_emit (cle, contact_list_editor_signals[LIST_DELETED], 0,
- status, cle->card);
+ status, cle->contact);
/* always close the dialog after we successfully delete a list */
- if (status == E_BOOK_STATUS_SUCCESS)
+ if (status == E_BOOK_ERROR_OK)
close_dialog (cle);
g_object_unref (cle); /* release reference held for callback */
@@ -505,9 +550,9 @@ static void
delete_cb (GtkWidget *widget, gpointer data)
{
EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
- ECard *card = cle->card;
+ EContact *contact = cle->contact;
- g_object_ref (card);
+ g_object_ref (contact);
if (e_contact_editor_confirm_delete(GTK_WINDOW(cle->app))) {
@@ -518,11 +563,11 @@ delete_cb (GtkWidget *widget, gpointer data)
cle->in_async_call = TRUE;
g_object_ref (cle); /* hold reference for callback */
- e_book_remove_card (cle->book, card, (EBookCallback)list_deleted_cb, cle);
+ e_book_async_remove_contact (cle->book, contact, (EBookCallback)list_deleted_cb, cle);
}
}
- g_object_unref (card);
+ g_object_unref (contact);
}
static
@@ -578,7 +623,7 @@ contact_list_editor_destroy_notify (gpointer data,
EContactListEditor *
e_contact_list_editor_new (EBook *book,
- ECard *list_card,
+ EContact *list_contact,
gboolean is_new_list,
gboolean editable)
{
@@ -592,7 +637,7 @@ e_contact_list_editor_new (EBook *book,
g_object_set (ce,
"book", book,
- "card", list_card,
+ "contact", list_contact,
"is_new_list", is_new_list,
"editable", editable,
NULL);
@@ -616,10 +661,10 @@ e_contact_list_editor_set_property (GObject *object, guint prop_id,
g_object_ref (editor->book);
/* XXX more here about editable/etc. */
break;
- case PROP_CARD:
- if (editor->card)
- g_object_unref (editor->card);
- editor->card = e_card_duplicate(E_CARD(g_value_get_object (value)));
+ case PROP_CONTACT:
+ if (editor->contact)
+ g_object_unref (editor->contact);
+ editor->contact = e_contact_duplicate(E_CONTACT(g_value_get_object (value)));
fill_in_info(editor);
editor->changed = FALSE;
command_state_changed (editor);
@@ -665,9 +710,9 @@ e_contact_list_editor_get_property (GObject *object, guint prop_id,
g_value_set_object (value, editor->book);
break;
- case PROP_CARD:
+ case PROP_CONTACT:
extract_info(editor);
- g_value_set_object (value, editor->card);
+ g_value_set_object (value, editor->contact);
break;
case PROP_IS_NEW_LIST:
@@ -822,7 +867,7 @@ table_drag_motion_cb (ETable *table, int row, int col,
for (p = context->targets; p != NULL; p = p->next) {
char *possible_type;
- possible_type = gdk_atom_name ((GdkAtom) p->data);
+ possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
if (!strcmp (possible_type, VCARD_TYPE)) {
g_free (possible_type);
gdk_drag_status (context, GDK_ACTION_LINK, time);
@@ -866,28 +911,24 @@ table_drag_data_received_cb (ETable *table, int row, int col,
if (!strcmp (target_type, VCARD_TYPE)) {
- GList *card_list = e_card_load_cards_from_string_with_default_charset (selection_data->data, "ISO-8859-1");
+ GList *contact_list = eab_contact_list_from_string (selection_data->data);
GList *c;
- if (card_list)
+ if (contact_list)
handled = TRUE;
- for (c = card_list; c; c = c->next) {
- ECard *ecard = c->data;
-
- if (!e_card_evolution_list (ecard)) {
- ECardSimple *simple = e_card_simple_new (ecard);
+ for (c = contact_list; c; c = c->next) {
+ EContact *contact = c->data;
- e_contact_list_model_add_card (E_CONTACT_LIST_MODEL (editor->model),
- simple);
-
- g_object_unref (simple);
+ if (!e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ e_contact_list_model_add_contact (E_CONTACT_LIST_MODEL (editor->model),
+ contact);
changed = TRUE;
}
}
- g_list_foreach (card_list, (GFunc)g_object_unref, NULL);
- g_list_free (card_list);
+ g_list_foreach (contact_list, (GFunc)g_object_unref, NULL);
+ g_list_free (contact_list);
/* Skip to the end of the list */
if (adj->upper - adj->lower > adj->page_size)
@@ -902,6 +943,219 @@ table_drag_data_received_cb (ETable *table, int row, int col,
gtk_drag_finish (context, handled, FALSE, time);
}
+static gboolean
+set_image_from_data (EContactListEditor *editor,
+ char *data, int length)
+{
+ gboolean rv = FALSE;
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ GdkPixbuf *pixbuf;
+
+ gdk_pixbuf_loader_write (loader, data, length, NULL);
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf)
+ gdk_pixbuf_ref (pixbuf);
+ gdk_pixbuf_loader_close (loader, NULL);
+ g_object_unref (loader);
+
+ if (pixbuf) {
+ GdkPixbuf *scaled;
+ GdkPixbuf *composite;
+
+ float scale;
+ int new_height, new_width;
+
+ new_height = gdk_pixbuf_get_height (pixbuf);
+ new_width = gdk_pixbuf_get_width (pixbuf);
+
+ printf ("new dimensions = (%d,%d)\n", new_width, new_height);
+
+ if (editor->list_image_height < new_height
+ || editor->list_image_width < new_width) {
+ /* we need to scale down */
+ printf ("we need to scale down\n");
+ if (new_height > new_width)
+ scale = (float)editor->list_image_height / new_height;
+ else
+ scale = (float)editor->list_image_width / new_width;
+ }
+ else {
+ /* we need to scale up */
+ printf ("we need to scale up\n");
+ if (new_height > new_width)
+ scale = (float)new_height / editor->list_image_height;
+ else
+ scale = (float)new_width / editor->list_image_width;
+ }
+
+ printf ("scale = %g\n", scale);
+
+ new_width *= scale;
+ new_height *= scale;
+ new_width = MIN (new_width, editor->list_image_width);
+ new_height = MIN (new_height, editor->list_image_height);
+
+ printf ("new scaled dimensions = (%d,%d)\n", new_width, new_height);
+
+ scaled = gdk_pixbuf_scale_simple (pixbuf,
+ new_width, new_height,
+ GDK_INTERP_BILINEAR);
+
+ composite = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (pixbuf),
+ editor->list_image_width, editor->list_image_height);
+
+ gdk_pixbuf_fill (composite, 0x00000000);
+
+ gdk_pixbuf_copy_area (scaled, 0, 0, new_width, new_height,
+ composite,
+ editor->list_image_width / 2 - new_width / 2,
+ editor->list_image_height / 2 - new_height / 2);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (editor->list_image), composite);
+ gdk_pixbuf_unref (pixbuf);
+ gdk_pixbuf_unref (scaled);
+ gdk_pixbuf_unref (composite);
+
+ rv = TRUE;
+ }
+
+ return rv;
+}
+
+static gboolean
+image_drag_motion_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y, guint time, EContactListEditor *editor)
+{
+ GList *p;
+
+ for (p = context->targets; p != NULL; p = p->next) {
+ char *possible_type;
+
+ possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
+ if (!strcmp (possible_type, URI_LIST_TYPE)) {
+ g_free (possible_type);
+ gdk_drag_status (context, GDK_ACTION_COPY, time);
+ return TRUE;
+ }
+
+ g_free (possible_type);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+image_drag_drop_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y, guint time, EContactListEditor *editor)
+{
+ GList *p;
+
+ if (context->targets == NULL)
+ return FALSE;
+
+
+ for (p = context->targets; p != NULL; p = p->next) {
+ char *possible_type;
+
+ possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
+ if (!strcmp (possible_type, URI_LIST_TYPE)) {
+ g_free (possible_type);
+ gtk_drag_get_data (widget, context,
+ GDK_POINTER_TO_ATOM (p->data),
+ time);
+ return TRUE;
+ }
+
+ g_free (possible_type);
+ }
+
+ return FALSE;
+}
+
+static void
+image_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time, EContactListEditor *editor)
+{
+ char *target_type;
+ gboolean changed = FALSE;
+ gboolean handled = FALSE;
+
+ target_type = gdk_atom_name (selection_data->target);
+
+ printf ("target_type == %s\n", target_type);
+
+ if (!strcmp (target_type, URI_LIST_TYPE)) {
+ GnomeVFSResult result;
+ GnomeVFSHandle *handle;
+ char *uri;
+ char *nl = strstr (selection_data->data, "\r\n");
+ char *buf = NULL;
+ GnomeVFSFileInfo info;
+
+ if (nl)
+ uri = g_strndup (selection_data->data, nl - (char*)selection_data->data);
+ else
+ uri = g_strdup (selection_data->data);
+
+ printf ("uri == %s\n", uri);
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_DEFAULT);
+ if (result == GNOME_VFS_OK) {
+ GnomeVFSFileSize num_left;
+ GnomeVFSFileSize num_read;
+ GnomeVFSFileSize total_read;
+
+ printf ("file size = %d\n", (int)info.size);
+ buf = g_malloc (info.size);
+
+ num_left = info.size;
+ total_read = 0;
+
+ while ((result = gnome_vfs_read (handle, buf + total_read, num_left, &num_read)) == GNOME_VFS_OK) {
+ num_left -= num_read;
+ total_read += num_read;
+ }
+
+ printf ("read %d bytes\n", (int)total_read);
+ if (set_image_from_data (editor, buf, total_read)) {
+ changed = TRUE;
+ handled = TRUE;
+ g_free (editor->image_buf);
+ editor->image_buf = buf;
+ editor->image_buf_size = total_read;
+ }
+ else {
+ /* XXX we should pop up a
+ warning dialog here */
+ g_free (buf);
+ }
+ }
+
+ gnome_vfs_close (handle);
+ }
+ else {
+ printf ("gnome_vfs_open failed (%s)\n", gnome_vfs_result_to_string (result));
+ }
+
+ g_free (uri);
+
+ if (changed) {
+ editor->changed = TRUE;
+ command_state_changed (editor);
+ }
+ }
+
+ gtk_drag_finish (context, handled, FALSE, time);
+}
+
static void
command_state_changed (EContactListEditor *editor)
{
@@ -926,48 +1180,43 @@ command_state_changed (EContactListEditor *editor)
static void
extract_info(EContactListEditor *editor)
{
- ECard *card = editor->card;
- if (card) {
+ EContact *contact = editor->contact;
+ if (contact) {
int i;
- EList *email_list;
- EIterator *email_iter;
+ GList *email_list;
char *string = gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1);
- if (string && *string)
- g_object_set (card,
- "file_as", string,
- "full_name", string,
- NULL);
+ if (string && *string) {
+ e_contact_set (contact, E_CONTACT_FILE_AS, string);
+ e_contact_set (contact, E_CONTACT_FULL_NAME, string);
+ }
g_free (string);
-
- g_object_set (card,
- "list", GINT_TO_POINTER (TRUE),
- "list_show_addresses",
- GINT_TO_POINTER (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton))),
- NULL);
-
- g_object_get (card,
- "email", &email_list,
- NULL);
-
- /* clear the email list */
- email_iter = e_list_get_iterator (email_list);
- e_iterator_last (email_iter);
- while (e_iterator_is_valid (E_ITERATOR (email_iter))) {
- e_iterator_delete (E_ITERATOR (email_iter));
- }
- g_object_unref (email_iter);
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
+ e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES,
+ GINT_TO_POINTER (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton))));
+ email_list = NULL;
/* then refill it from the contact list model */
for (i = 0; i < e_table_model_row_count (editor->model); i ++) {
- const EDestination *dest = e_contact_list_model_get_destination (E_CONTACT_LIST_MODEL (editor->model), i);
- gchar *dest_xml = e_destination_export (dest);
- if (dest_xml) {
- e_list_append (email_list, dest_xml);
- }
- g_free (dest_xml);
+ const EABDestination *dest = e_contact_list_model_get_destination (E_CONTACT_LIST_MODEL (editor->model), i);
+ gchar *dest_xml = eab_destination_export (dest);
+ if (dest_xml)
+ email_list = g_list_append (email_list, dest_xml);
+ }
+
+ e_contact_set (contact, E_CONTACT_EMAIL, email_list);
+
+ /* XXX free email_list? */
+
+ if (editor->image_buf) {
+ EContactPhoto photo;
+
+ photo.data = editor->image_buf;
+ photo.length = editor->image_buf_size;
+
+ e_contact_set (contact, E_CONTACT_LOGO, &photo);
}
g_object_unref (email_list);
}
@@ -976,19 +1225,18 @@ extract_info(EContactListEditor *editor)
static void
fill_in_info(EContactListEditor *editor)
{
- if (editor->card) {
+ if (editor->contact) {
+ EContactPhoto *photo;
char *file_as;
gboolean show_addresses = FALSE;
gboolean is_evolution_list = FALSE;
- EList *email_list;
- EIterator *email_iter;
+ GList *email_list;
+ GList *iter;
- g_object_get (editor->card,
- "file_as", &file_as,
- "email", &email_list,
- "list", &is_evolution_list,
- "list_show_addresses", &show_addresses,
- NULL);
+ file_as = e_contact_get_const (editor->contact, E_CONTACT_FILE_AS);
+ email_list = e_contact_get (editor->contact, E_CONTACT_EMAIL);
+ is_evolution_list = GPOINTER_TO_INT (e_contact_get (editor->contact, E_CONTACT_IS_LIST));
+ show_addresses = GPOINTER_TO_INT (e_contact_get (editor->contact, E_CONTACT_LIST_SHOW_ADDRESSES));
gtk_editable_delete_text (GTK_EDITABLE (editor->list_name_entry), 0, -1);
if (file_as) {
@@ -1001,20 +1249,24 @@ fill_in_info(EContactListEditor *editor)
e_contact_list_model_remove_all (E_CONTACT_LIST_MODEL (editor->model));
- email_iter = e_list_get_iterator (email_list);
-
- while (e_iterator_is_valid (email_iter)) {
- const char *dest_xml = e_iterator_get (email_iter);
- EDestination *dest;
+ for (iter = email_list; iter; iter = iter->next) {
+ char *dest_xml = iter->data;
+ EABDestination *dest;
/* g_message ("incoming xml: [%s]", dest_xml); */
- dest = e_destination_import (dest_xml);
+ dest = eab_destination_import (dest_xml);
if (dest != NULL) {
e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (editor->model), dest);
}
+ }
+
+ /* XXX free email_list */
- e_iterator_next (email_iter);
+ photo = e_contact_get (editor->contact, E_CONTACT_LOGO);
+ if (photo) {
+ set_image_from_data (editor, photo->data, photo->length);
+ e_contact_photo_free (photo);
}
g_object_unref (email_list);
}
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.h b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
index 184145a0f7..62334c17bf 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
@@ -26,9 +26,8 @@
#include <glade/glade.h>
#include <gal/e-table/e-table-model.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include "addressbook/backend/ebook/e-book-async.h"
+#include "addressbook/backend/ebook/e-contact.h"
G_BEGIN_DECLS
@@ -48,7 +47,7 @@ struct _EContactListEditor
/* item specific fields */
EBook *book;
- ECard *card;
+ EContact *contact;
/* UI handler */
BonoboUIComponent *uic;
@@ -62,12 +61,19 @@ struct _EContactListEditor
GtkWidget *list_name_entry;
GtkWidget *add_button;
GtkWidget *remove_button;
+ GtkWidget *list_image_button;
GtkWidget *visible_addrs_checkbutton;
+ GtkWidget *list_image;
+ int list_image_width;
+ int list_image_height;
- /* Whether we are editing a new card or an existing one */
+ char *image_buf;
+ int image_buf_size;
+
+ /* Whether we are editing a new contact or an existing one */
guint is_new_list : 1;
- /* Whether the card has been changed since bringing up the contact editor */
+ /* Whether the contact has been changed since bringing up the contact editor */
guint changed : 1;
/* Whether the contact editor will accept modifications */
@@ -83,14 +89,14 @@ struct _EContactListEditorClass
/* Notification signals */
- void (* list_added) (EContactListEditor *cle, EBookStatus status, ECard *card);
- void (* list_modified) (EContactListEditor *cle, EBookStatus status, ECard *card);
- void (* list_deleted) (EContactListEditor *cle, EBookStatus status, ECard *card);
+ void (* list_added) (EContactListEditor *cle, EBookStatus status, EContact *contact);
+ void (* list_modified) (EContactListEditor *cle, EBookStatus status, EContact *contact);
+ void (* list_deleted) (EContactListEditor *cle, EBookStatus status, EContact *contact);
void (* editor_closed) (EContactListEditor *cle);
};
EContactListEditor *e_contact_list_editor_new (EBook *book,
- ECard *list_card,
+ EContact *list_contact,
gboolean is_new_list,
gboolean editable);
GType e_contact_list_editor_get_type (void);
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.c b/addressbook/gui/contact-list-editor/e-contact-list-model.c
index 89354aaece..80bc29b7a9 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.c
@@ -30,7 +30,7 @@ contact_list_value_at (ETableModel *etc, int col, int row)
{
EContactListModel *model = E_CONTACT_LIST_MODEL (etc);
- return (void *) e_destination_get_textrep (model->data[row], TRUE);
+ return (void *) eab_destination_get_textrep (model->data[row], TRUE);
}
/* This function sets the value at a particular point in our ETableModel. */
@@ -127,7 +127,7 @@ e_contact_list_model_init (GtkObject *object)
model->data_alloc = 10;
model->data_count = 0;
- model->data = g_new (EDestination*, model->data_alloc);
+ model->data = g_new (EABDestination*, model->data_alloc);
}
GType
@@ -172,16 +172,16 @@ e_contact_list_model_new ()
}
void
-e_contact_list_model_add_destination (EContactListModel *model, EDestination *dest)
+e_contact_list_model_add_destination (EContactListModel *model, EABDestination *dest)
{
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (E_IS_DESTINATION (dest));
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
e_table_model_pre_change (E_TABLE_MODEL (model));
if (model->data_count + 1 >= model->data_alloc) {
model->data_alloc *= 2;
- model->data = g_renew (EDestination*, model->data, model->data_alloc);
+ model->data = g_renew (EABDestination*, model->data, model->data_alloc);
}
model->data[model->data_count ++] = dest;
@@ -194,28 +194,28 @@ void
e_contact_list_model_add_email (EContactListModel *model,
const char *email)
{
- EDestination *new_dest;
+ EABDestination *new_dest;
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
g_return_if_fail (email != NULL);
- new_dest = e_destination_new ();
- e_destination_set_email (new_dest, email);
+ new_dest = eab_destination_new ();
+ eab_destination_set_email (new_dest, email);
e_contact_list_model_add_destination (model, new_dest);
}
void
-e_contact_list_model_add_card (EContactListModel *model,
- ECardSimple *simple)
+e_contact_list_model_add_contact (EContactListModel *model,
+ EContact *contact)
{
- EDestination *new_dest;
+ EABDestination *new_dest;
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (E_IS_CARD_SIMPLE (simple));
+ g_return_if_fail (E_IS_CONTACT (contact));
- new_dest = e_destination_new ();
- e_destination_set_card (new_dest, simple->card, 0); /* Hard-wired for default e-mail */
+ new_dest = eab_destination_new ();
+ eab_destination_set_contact (new_dest, contact, 0); /* Hard-wired for default e-mail */
e_contact_list_model_add_destination (model, new_dest);
}
@@ -229,7 +229,7 @@ e_contact_list_model_remove_row (EContactListModel *model, int row)
e_table_model_pre_change (E_TABLE_MODEL (model));
g_object_unref (model->data[row]);
- memmove (model->data + row, model->data + row + 1, sizeof (EDestination*) * (model->data_count - row - 1));
+ memmove (model->data + row, model->data + row + 1, sizeof (EABDestination*) * (model->data_count - row - 1));
model->data_count --;
e_table_model_row_deleted (E_TABLE_MODEL (model), row);
@@ -255,7 +255,7 @@ e_contact_list_model_remove_all (EContactListModel *model)
}
-const EDestination *
+const EABDestination *
e_contact_list_model_get_destination (EContactListModel *model, int row)
{
g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), NULL);
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.h b/addressbook/gui/contact-list-editor/e-contact-list-model.h
index bb07d83544..92d3d9bc60 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.h
@@ -4,10 +4,9 @@
#include <gtk/gtk.h>
#include <gal/e-table/e-table-model.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-#include "addressbook/backend/ebook/e-destination.h"
+#include "addressbook/backend/ebook/e-book-async.h"
+#include "addressbook/backend/ebook/e-contact.h"
+#include "addressbook/util/eab-destination.h"
G_BEGIN_DECLS
@@ -23,7 +22,7 @@ typedef struct _EContactListModelClass EContactListModelClass;
struct _EContactListModel {
ETableModel parent;
- EDestination **data;
+ EABDestination **data;
int data_count;
int data_alloc;
};
@@ -38,14 +37,14 @@ GType e_contact_list_model_get_type (void);
void e_contact_list_model_construct (EContactListModel *model);
ETableModel *e_contact_list_model_new (void);
-void e_contact_list_model_add_destination (EContactListModel *model, EDestination *dest);
+void e_contact_list_model_add_destination (EContactListModel *model, EABDestination *dest);
void e_contact_list_model_add_email (EContactListModel *model, const char *email);
-void e_contact_list_model_add_card (EContactListModel *model, ECardSimple *simple);
+void e_contact_list_model_add_contact (EContactListModel *model, EContact *contact);
void e_contact_list_model_remove_row (EContactListModel *model, int row);
void e_contact_list_model_remove_all (EContactListModel *model);
-const EDestination *e_contact_list_model_get_destination (EContactListModel *model, int row);
+const EABDestination *e_contact_list_model_get_destination (EContactListModel *model, int row);
G_END_DECLS
diff --git a/addressbook/gui/merging/.cvsignore b/addressbook/gui/merging/.cvsignore
index d6c55c7345..b6fa83ca4c 100644
--- a/addressbook/gui/merging/.cvsignore
+++ b/addressbook/gui/merging/.cvsignore
@@ -5,3 +5,4 @@ Makefile
Makefile.in
*.lo
*.la
+*.gladep
diff --git a/addressbook/gui/merging/Makefile.am b/addressbook/gui/merging/Makefile.am
index f30edd5745..4627f30594 100644
--- a/addressbook/gui/merging/Makefile.am
+++ b/addressbook/gui/merging/Makefile.am
@@ -1,7 +1,8 @@
INCLUDES = \
- -DG_LOG_DOMAIN=\"e-card-gui\" \
+ -DG_LOG_DOMAIN=\"eab-contact-merging\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook \
-I$(top_srcdir)/addressbook/backend \
-I$(top_builddir)/addressbook/backend \
-DG_DISABLE_DEPRECATED \
@@ -11,15 +12,17 @@ INCLUDES = \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
noinst_LTLIBRARIES = \
- libecardmerging.la
+ libeabbookmerging.la
-libecardmerging_la_SOURCES = \
- e-card-merging.c \
- e-card-merging.h
+libeabbookmerging_la_SOURCES = \
+ eab-contact-compare.c \
+ eab-contact-compare.h \
+ eab-contact-merging.c \
+ eab-contact-merging.h
-glade_DATA = e-card-duplicate-detected.glade \
- e-card-merging-book-commit-duplicate-detected.glade
+glade_DATA = eab-contact-duplicate-detected.glade \
+ eab-contact-commit-duplicate-detected.glade
EXTRA_DIST = \
$(glade_DATA)
diff --git a/addressbook/gui/merging/e-card-merging.c b/addressbook/gui/merging/e-card-merging.c
deleted file mode 100644
index f2322e772c..0000000000
--- a/addressbook/gui/merging/e-card-merging.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Code for checking for duplicates when doing ECard work.
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com>
- *
- * Copyright 2001, Ximian, Inc.
- */
-
-#include <config.h>
-
-#include "e-card-merging.h"
-#include <ebook/e-card-compare.h>
-#include <glade/glade.h>
-#include <gtk/gtksignal.h>
-#include "addressbook/gui/widgets/e-minicard-widget.h"
-
-typedef enum {
- E_CARD_MERGING_ADD,
- E_CARD_MERGING_COMMIT
-} ECardMergingOpType;
-
-typedef struct {
- ECardMergingOpType op;
- EBook *book;
- ECard *card;
- EBookIdCallback id_cb;
- EBookCallback cb;
- gpointer closure;
-} ECardMergingLookup;
-
-static void
-free_lookup (ECardMergingLookup *lookup)
-{
- g_object_unref (lookup->book);
- g_object_unref (lookup->card);
-
- g_free (lookup);
-}
-
-static void
-final_id_cb (EBook *book, EBookStatus status, const char *id, gpointer closure)
-{
- ECardMergingLookup *lookup = closure;
-
- if (lookup->id_cb)
- lookup->id_cb (lookup->book, status, id, lookup->closure);
-
- free_lookup (lookup);
-}
-
-static void
-final_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- ECardMergingLookup *lookup = closure;
-
- if (lookup->cb)
- lookup->cb (lookup->book, status, lookup->closure);
-
- free_lookup (lookup);
-}
-
-static void
-doit (ECardMergingLookup *lookup)
-{
- if (lookup->op == E_CARD_MERGING_ADD)
- e_book_add_card (lookup->book, lookup->card, final_id_cb, lookup);
- else if (lookup->op == E_CARD_MERGING_COMMIT)
- e_book_commit_card (lookup->book, lookup->card, final_cb, lookup);
-}
-
-static void
-cancelit (ECardMergingLookup *lookup)
-{
- if (lookup->op == E_CARD_MERGING_ADD) {
- if (lookup->id_cb)
- final_id_cb (lookup->book, E_BOOK_STATUS_CANCELLED, NULL, lookup);
- } else if (lookup->op == E_CARD_MERGING_COMMIT) {
- if (lookup->cb)
- final_cb (lookup->book, E_BOOK_STATUS_CANCELLED, lookup);
- }
-}
-
-static void
-response (GtkWidget *dialog, int response, ECardMergingLookup *lookup)
-{
- gtk_widget_destroy (dialog);
-
- switch (response) {
- case 0:
- doit (lookup);
- break;
- case 1:
- cancelit (lookup);
- break;
- }
-}
-
-static void
-match_query_callback (ECard *card, ECard *match, ECardMatchType type, gpointer closure)
-{
- ECardMergingLookup *lookup = closure;
-
- if ((gint) type <= (gint) E_CARD_MATCH_VAGUE) {
- doit (lookup);
- } else {
- GladeXML *ui;
-
- GtkWidget *widget;
-
- if (lookup->op == E_CARD_MERGING_ADD)
- ui = glade_xml_new (EVOLUTION_GLADEDIR "/e-card-duplicate-detected.glade", NULL, NULL);
- else if (lookup->op == E_CARD_MERGING_COMMIT)
- ui = glade_xml_new (EVOLUTION_GLADEDIR "/e-card-merging-book-commit-duplicate-detected.glade", NULL, NULL);
- else {
- doit (lookup);
- return;
- }
-
- widget = glade_xml_get_widget (ui, "custom-old-card");
- g_object_set (widget,
- "card", match,
- NULL);
-
- widget = glade_xml_get_widget (ui, "custom-new-card");
- g_object_set (widget,
- "card", card,
- NULL);
-
- widget = glade_xml_get_widget (ui, "dialog-duplicate-contact");
-
- g_signal_connect (widget, "response",
- G_CALLBACK (response), lookup);
-
- gtk_widget_show_all (widget);
- }
-}
-
-gboolean
-e_card_merging_book_add_card (EBook *book,
- ECard *card,
- EBookIdCallback cb,
- gpointer closure)
-{
- ECardMergingLookup *lookup;
-
- lookup = g_new (ECardMergingLookup, 1);
-
- lookup->op = E_CARD_MERGING_ADD;
- lookup->book = g_object_ref (book);
- lookup->card = g_object_ref (card);
- lookup->id_cb = cb;
- lookup->closure = closure;
-
- e_card_locate_match_full (book, card, NULL, match_query_callback, lookup);
-
- return TRUE;
-}
-
-gboolean
-e_card_merging_book_commit_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure)
-{
- ECardMergingLookup *lookup;
- GList *avoid;
-
- lookup = g_new (ECardMergingLookup, 1);
-
- lookup->op = E_CARD_MERGING_COMMIT;
- lookup->book = g_object_ref (book);
- lookup->card = g_object_ref (card);
- lookup->cb = cb;
- lookup->closure = closure;
-
- avoid = g_list_append (NULL, card);
-
- e_card_locate_match_full (book, card, avoid, match_query_callback, lookup);
-
- g_list_free (avoid);
-
- return TRUE;
-}
-
-GtkWidget *
-e_card_merging_create_old_card(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
-
-GtkWidget *
-e_card_merging_create_old_card(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
-{
- return e_minicard_widget_new ();
-}
diff --git a/addressbook/gui/merging/e-card-merging.h b/addressbook/gui/merging/e-card-merging.h
deleted file mode 100644
index 8ea1f9f018..0000000000
--- a/addressbook/gui/merging/e-card-merging.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * The Evolution addressbook client object.
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com>
- *
- * Copyright 2001, Ximian, Inc.
- */
-
-#ifndef __E_CARD_MERGING_H__
-#define __E_CARD_MERGING_H__
-
-#include <addressbook/backend/ebook/e-book.h>
-
-G_BEGIN_DECLS
-
-gboolean e_card_merging_book_add_card (EBook *book,
- ECard *card,
- EBookIdCallback cb,
- gpointer closure);
-gboolean e_card_merging_book_commit_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure);
-
-G_END_DECLS
-
-#endif /* ! __E_CARD_MERGING_H__ */
diff --git a/addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade b/addressbook/gui/merging/eab-contact-commit-duplicate-detected.glade
index f7cfd259e5..789c465d92 100644
--- a/addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade
+++ b/addressbook/gui/merging/eab-contact-commit-duplicate-detected.glade
@@ -68,12 +68,12 @@
<property name="column_spacing">6</property>
<child>
- <widget class="Custom" id="custom-old-card">
+ <widget class="Custom" id="custom-old-contact">
<property name="visible">True</property>
- <property name="creation_function">e_card_merging_create_old_card</property>
+ <property name="creation_function">_eab_contact_merging_create_contact_display</property>
<property name="int1">0</property>
<property name="int2">0</property>
- <property name="last_modification_time">Fri, 08 Jun 2001 01:33:22 GMT</property>
+ <property name="last_modification_time">Sun, 05 Oct 2003 03:54:20 GMT</property>
</widget>
<packing>
<property name="left_attach">1</property>
@@ -155,12 +155,12 @@ exists in this folder. Would you like to add it anyway?</property>
</child>
<child>
- <widget class="Custom" id="custom-new-card">
+ <widget class="Custom" id="custom-new-contact">
<property name="visible">True</property>
- <property name="creation_function">e_card_merging_create_old_card</property>
+ <property name="creation_function">_eab_contact_merging_create_contact_display</property>
<property name="int1">0</property>
<property name="int2">0</property>
- <property name="last_modification_time">Fri, 08 Jun 2001 01:33:22 GMT</property>
+ <property name="last_modification_time">Sun, 05 Oct 2003 03:53:42 GMT</property>
</widget>
<packing>
<property name="left_attach">1</property>
diff --git a/addressbook/backend/ebook/e-card-compare.c b/addressbook/gui/merging/eab-contact-compare.c
index 2413d987e5..409b1bce81 100644
--- a/addressbook/backend/ebook/e-card-compare.c
+++ b/addressbook/gui/merging/eab-contact-compare.c
@@ -1,11 +1,12 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-card-compare.c
+ * eab-contact-compare.c
*
- * Copyright (C) 2001 Ximian, Inc.
+ * Copyright (C) 2001, 2002, 2003 Ximian, Inc.
*
- * Developed by Jon Trowbridge <trow@ximian.com>
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
*/
/*
@@ -27,18 +28,18 @@
#include <config.h>
#include <ctype.h>
#include <string.h>
-#include "e-book-util.h"
-#include "e-card-compare.h"
+#include "util/eab-book-util.h"
+#include "eab-contact-compare.h"
/* This is an "optimistic" combiner: the best of the two outcomes is
selected. */
-static ECardMatchType
-combine_comparisons (ECardMatchType prev,
- ECardMatchType new_info)
+static EABContactMatchType
+combine_comparisons (EABContactMatchType prev,
+ EABContactMatchType new_info)
{
- if (new_info == E_CARD_MATCH_NOT_APPLICABLE)
+ if (new_info == EAB_CONTACT_MATCH_NOT_APPLICABLE)
return prev;
- return (ECardMatchType) MAX ((gint) prev, (gint) new_info);
+ return (EABContactMatchType) MAX ((gint) prev, (gint) new_info);
}
@@ -131,30 +132,34 @@ name_fragment_match_with_synonyms (const gchar *a, const gchar *b, gboolean stri
return FALSE;
}
-ECardMatchType
-e_card_compare_name_to_string (ECard *card, const gchar *str)
+EABContactMatchType
+eab_contact_compare_name_to_string (EContact *contact, const gchar *str)
{
- return e_card_compare_name_to_string_full (card, str, FALSE, NULL, NULL, NULL);
+ return eab_contact_compare_name_to_string_full (contact, str, FALSE, NULL, NULL, NULL);
}
-ECardMatchType
-e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allow_partial_matches,
- gint *matched_parts_out, ECardMatchPart *first_matched_part_out, gint *matched_character_count_out)
+EABContactMatchType
+eab_contact_compare_name_to_string_full (EContact *contact, const gchar *str, gboolean allow_partial_matches,
+ gint *matched_parts_out, EABContactMatchPart *first_matched_part_out, gint *matched_character_count_out)
{
gchar **namev, **givenv = NULL, **addv = NULL, **familyv = NULL;
- gint matched_parts = E_CARD_MATCH_PART_NONE;
- ECardMatchPart first_matched_part = E_CARD_MATCH_PART_NONE;
- ECardMatchPart this_part_match = E_CARD_MATCH_PART_NOT_APPLICABLE;
- ECardMatchType match_type;
+ gint matched_parts = EAB_CONTACT_MATCH_PART_NONE;
+ EABContactMatchPart first_matched_part = EAB_CONTACT_MATCH_PART_NONE;
+ EABContactMatchPart this_part_match = EAB_CONTACT_MATCH_PART_NOT_APPLICABLE;
+ EABContactMatchType match_type;
+ EContactName *contact_name;
gint match_count = 0, matched_character_count = 0, fragment_count;
gint i, j;
gchar *str_cpy, *s;
- g_return_val_if_fail (E_IS_CARD (card), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card->name != NULL, E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (str != NULL, E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (E_IS_CONTACT (contact), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+
+ if (!e_contact_get_const (contact, E_CONTACT_FULL_NAME))
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ if (str == NULL)
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
str_cpy = s = g_strdup (str);
while (*s) {
@@ -165,12 +170,16 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
namev = g_strsplit (str_cpy, " ", 0);
g_free (str_cpy);
- if (card->name->given)
- givenv = g_strsplit (card->name->given, " ", 0);
- if (card->name->additional)
- addv = g_strsplit (card->name->additional, " ", 0);
- if (card->name->family)
- familyv = g_strsplit (card->name->family, " ", 0);
+ contact_name = e_contact_get (contact, E_CONTACT_NAME);
+
+ if (contact_name->given)
+ givenv = g_strsplit (contact_name->given, " ", 0);
+ if (contact_name->additional)
+ addv = g_strsplit (contact_name->additional, " ", 0);
+ if (contact_name->family)
+ familyv = g_strsplit (contact_name->family, " ", 0);
+
+ e_contact_name_free (contact_name);
fragment_count = 0;
for (i = 0; givenv && givenv[i]; ++i)
@@ -180,21 +189,21 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
for (i = 0; familyv && familyv[i]; ++i)
++fragment_count;
- for (i = 0; namev[i] && this_part_match != E_CARD_MATCH_PART_NONE; ++i) {
+ for (i = 0; namev[i] && this_part_match != EAB_CONTACT_MATCH_PART_NONE; ++i) {
if (*namev[i]) {
- this_part_match = E_CARD_MATCH_PART_NONE;
+ this_part_match = EAB_CONTACT_MATCH_PART_NONE;
/* When we are allowing partials, we are strict about the matches we allow.
Does this make sense? Not really, but it does the right thing for the purposes
of completion. */
- if (givenv && this_part_match == E_CARD_MATCH_PART_NONE) {
+ if (givenv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
for (j = 0; givenv[j]; ++j) {
if (name_fragment_match_with_synonyms (givenv[j], namev[i], allow_partial_matches)) {
- this_part_match = E_CARD_MATCH_PART_GIVEN_NAME;
+ this_part_match = EAB_CONTACT_MATCH_PART_GIVEN_NAME;
/* We remove a piece of a name once it has been matched against, so
that "john john" won't match "john doe". */
@@ -205,11 +214,11 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
}
}
- if (addv && this_part_match == E_CARD_MATCH_PART_NONE) {
+ if (addv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
for (j = 0; addv[j]; ++j) {
if (name_fragment_match_with_synonyms (addv[j], namev[i], allow_partial_matches)) {
- this_part_match = E_CARD_MATCH_PART_ADDITIONAL_NAME;
+ this_part_match = EAB_CONTACT_MATCH_PART_ADDITIONAL_NAME;
g_free (addv[j]);
addv[j] = g_strdup ("");
@@ -218,12 +227,12 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
}
}
- if (familyv && this_part_match == E_CARD_MATCH_PART_NONE) {
+ if (familyv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
for (j = 0; familyv[j]; ++j) {
if (allow_partial_matches ? name_fragment_match_with_synonyms (familyv[j], namev[i], allow_partial_matches)
: !e_utf8_casefold_collate (familyv[j], namev[i])) {
- this_part_match = E_CARD_MATCH_PART_FAMILY_NAME;
+ this_part_match = EAB_CONTACT_MATCH_PART_FAMILY_NAME;
g_free (familyv[j]);
familyv[j] = g_strdup ("");
@@ -232,30 +241,30 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
}
}
- if (this_part_match != E_CARD_MATCH_PART_NONE) {
+ if (this_part_match != EAB_CONTACT_MATCH_PART_NONE) {
++match_count;
matched_character_count += g_utf8_strlen (namev[i], -1);
matched_parts |= this_part_match;
- if (first_matched_part == E_CARD_MATCH_PART_NONE)
+ if (first_matched_part == EAB_CONTACT_MATCH_PART_NONE)
first_matched_part = this_part_match;
}
}
}
- match_type = E_CARD_MATCH_NONE;
+ match_type = EAB_CONTACT_MATCH_NONE;
- if (this_part_match != E_CARD_MATCH_PART_NONE) {
+ if (this_part_match != EAB_CONTACT_MATCH_PART_NONE) {
if (match_count > 0)
- match_type = E_CARD_MATCH_VAGUE;
+ match_type = EAB_CONTACT_MATCH_VAGUE;
if (fragment_count == match_count) {
- match_type = E_CARD_MATCH_EXACT;
+ match_type = EAB_CONTACT_MATCH_EXACT;
} else if (fragment_count == match_count + 1) {
- match_type = E_CARD_MATCH_PARTIAL;
+ match_type = EAB_CONTACT_MATCH_PARTIAL;
}
}
@@ -275,21 +284,21 @@ e_card_compare_name_to_string_full (ECard *card, const gchar *str, gboolean allo
return match_type;
}
-ECardMatchType
-e_card_compare_name (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare_name (EContact *contact1, EContact *contact2)
{
- ECardName *a, *b;
+ EContactName *a, *b;
gint matches=0, possible=0;
gboolean given_match = FALSE, additional_match = FALSE, family_match = FALSE;
- g_return_val_if_fail (E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
- a = card1->name;
- b = card2->name;
+ a = e_contact_get (contact1, E_CONTACT_NAME);
+ b = e_contact_get (contact2, E_CONTACT_NAME);
if (a == NULL || b == NULL)
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
if (a->given && b->given) {
++possible;
@@ -316,35 +325,38 @@ e_card_compare_name (ECard *card1, ECard *card2)
}
}
+ e_contact_name_free (a);
+ e_contact_name_free (b);
+
/* Now look at the # of matches and try to intelligently map
- an E_CARD_MATCH_* type to it. Special consideration is given
+ an EAB_CONTACT_MATCH_* type to it. Special consideration is given
to family-name matches. */
if (possible == 0)
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
if (possible == 1)
- return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE;
+ return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;
if (possible == matches)
- return family_match ? E_CARD_MATCH_EXACT : E_CARD_MATCH_PARTIAL;
+ return family_match ? EAB_CONTACT_MATCH_EXACT : EAB_CONTACT_MATCH_PARTIAL;
if (possible == matches+1)
- return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE;
+ return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;
- return E_CARD_MATCH_NONE;
+ return EAB_CONTACT_MATCH_NONE;
}
/*** Nickname Comparisons ***/
-ECardMatchType
-e_card_compare_nickname (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare_nickname (EContact *contact1, EContact *contact2)
{
- g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
}
@@ -417,104 +429,115 @@ match_email_hostname (const gchar *addr1, const gchar *addr2)
return *addr1 == '.' || *addr2 == '.';
}
-static ECardMatchType
+static EABContactMatchType
compare_email_addresses (const gchar *addr1, const gchar *addr2)
{
if (addr1 == NULL || *addr1 == 0 ||
addr2 == NULL || *addr2 == 0)
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
if (match_email_username (addr1, addr2))
- return match_email_hostname (addr1, addr2) ? E_CARD_MATCH_EXACT : E_CARD_MATCH_VAGUE;
+ return match_email_hostname (addr1, addr2) ? EAB_CONTACT_MATCH_EXACT : EAB_CONTACT_MATCH_VAGUE;
- return E_CARD_MATCH_NONE;
+ return EAB_CONTACT_MATCH_NONE;
}
-ECardMatchType
-e_card_compare_email (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare_email (EContact *contact1, EContact *contact2)
{
- EIterator *i1, *i2;
- ECardMatchType match = E_CARD_MATCH_NOT_APPLICABLE;
+ EABContactMatchType match = EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ GList *contact1_email, *contact2_email;
+ GList *i1, *i2;
+
+ g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+
+ contact1_email = e_contact_get (contact1, E_CONTACT_EMAIL);
+ contact2_email = e_contact_get (contact2, E_CONTACT_EMAIL);
- g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ if (contact1_email == NULL || contact2_email == NULL) {
+ g_list_foreach (contact1_email, (GFunc)g_free, NULL);
+ g_list_free (contact1_email);
- if (card1->email == NULL || card2->email == NULL)
- return E_CARD_MATCH_NOT_APPLICABLE;
+ g_list_foreach (contact2_email, (GFunc)g_free, NULL);
+ g_list_free (contact2_email);
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ }
- i1 = e_list_get_iterator (card1->email);
- i2 = e_list_get_iterator (card2->email);
+ i1 = contact1_email;
/* Do pairwise-comparisons on all of the e-mail addresses. If
we find an exact match, there is no reason to keep
checking. */
- e_iterator_reset (i1);
- while (e_iterator_is_valid (i1) && match != E_CARD_MATCH_EXACT) {
- const gchar *addr1 = (const gchar *) e_iterator_get (i1);
+ while (i1 && match != EAB_CONTACT_MATCH_EXACT) {
+ char *addr1 = (char *) i1->data;
- e_iterator_reset (i2);
- while (e_iterator_is_valid (i2) && match != E_CARD_MATCH_EXACT) {
- const gchar *addr2 = (const gchar *) e_iterator_get (i2);
+ i2 = contact2_email;
+ while (i2 && match != EAB_CONTACT_MATCH_EXACT) {
+ char *addr2 = (char *) i2->data;
match = combine_comparisons (match, compare_email_addresses (addr1, addr2));
- e_iterator_next (i2);
+ i2 = i2->next;
}
- e_iterator_next (i1);
+ i1 = i1->next;
}
- g_object_unref (i1);
- g_object_unref (i2);
+ g_list_foreach (contact1_email, (GFunc)g_free, NULL);
+ g_list_free (contact1_email);
+
+ g_list_foreach (contact2_email, (GFunc)g_free, NULL);
+ g_list_free (contact2_email);
return match;
}
-ECardMatchType
-e_card_compare_address (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare_address (EContact *contact1, EContact *contact2)
{
- g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
/* Unimplemented */
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
}
-ECardMatchType
-e_card_compare_telephone (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare_telephone (EContact *contact1, EContact *contact2)
{
- g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
/* Unimplemented */
- return E_CARD_MATCH_NOT_APPLICABLE;
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
}
-ECardMatchType
-e_card_compare (ECard *card1, ECard *card2)
+EABContactMatchType
+eab_contact_compare (EContact *contact1, EContact *contact2)
{
- ECardMatchType result;
+ EABContactMatchType result;
- g_return_val_if_fail (card1 && E_IS_CARD (card1), E_CARD_MATCH_NOT_APPLICABLE);
- g_return_val_if_fail (card2 && E_IS_CARD (card2), E_CARD_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
+ g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);
- result = E_CARD_MATCH_NONE;
- result = combine_comparisons (result, e_card_compare_name (card1, card2));
- result = combine_comparisons (result, e_card_compare_nickname (card1, card2));
- result = combine_comparisons (result, e_card_compare_email (card1, card2));
- result = combine_comparisons (result, e_card_compare_address (card1, card2));
- result = combine_comparisons (result, e_card_compare_telephone (card1, card2));
+ result = EAB_CONTACT_MATCH_NONE;
+ result = combine_comparisons (result, eab_contact_compare_name (contact1, contact2));
+ result = combine_comparisons (result, eab_contact_compare_nickname (contact1, contact2));
+ result = combine_comparisons (result, eab_contact_compare_email (contact1, contact2));
+ result = combine_comparisons (result, eab_contact_compare_address (contact1, contact2));
+ result = combine_comparisons (result, eab_contact_compare_telephone (contact1, contact2));
return result;
}
typedef struct _MatchSearchInfo MatchSearchInfo;
struct _MatchSearchInfo {
- ECard *card;
+ EContact *contact;
GList *avoid;
- ECardMatchQueryCallback cb;
+ EABContactMatchQueryCallback cb;
gpointer closure;
};
@@ -522,7 +545,7 @@ static void
match_search_info_free (MatchSearchInfo *info)
{
if (info) {
- g_object_unref (info->card);
+ g_object_unref (info->contact);
/* This should already have been deallocated, but just in case... */
if (info->avoid) {
@@ -536,49 +559,51 @@ match_search_info_free (MatchSearchInfo *info)
}
static void
-simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
+query_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
{
+ /* XXX we need to free contacts */
MatchSearchInfo *info = (MatchSearchInfo *) closure;
- ECardMatchType best_match = E_CARD_MATCH_NONE;
- ECard *best_card = NULL;
- GList *remaining_cards = NULL;
+ EABContactMatchType best_match = EAB_CONTACT_MATCH_NONE;
+ EContact *best_contact = NULL;
+ GList *remaining_contacts = NULL;
const GList *i;
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) {
- info->cb (info->card, NULL, E_CARD_MATCH_NONE, info->closure);
+ if (status != E_BOOK_ERROR_OK) {
+ info->cb (info->contact, NULL, EAB_CONTACT_MATCH_NONE, info->closure);
match_search_info_free (info);
return;
}
- /* remove the cards we're to avoid from the list, if they're present */
- for (i = cards; i != NULL; i = g_list_next (i)) {
- ECard *this_card = E_CARD (i->data);
+ /* remove the contacts we're to avoid from the list, if they're present */
+ for (i = contacts; i != NULL; i = g_list_next (i)) {
+ EContact *this_contact = E_CONTACT (i->data);
GList *iterator;
gboolean avoid = FALSE;
for (iterator = info->avoid; iterator; iterator = iterator->next) {
- if (!strcmp (e_card_get_id (iterator->data), e_card_get_id (this_card))) {
+ if (!strcmp (e_contact_get_const (iterator->data, E_CONTACT_UID),
+ e_contact_get_const (this_contact, E_CONTACT_UID))) {
avoid = TRUE;
break;
}
}
if (!avoid)
- remaining_cards = g_list_prepend (remaining_cards, this_card);
+ remaining_contacts = g_list_prepend (remaining_contacts, this_contact);
}
- remaining_cards = g_list_reverse (remaining_cards);
+ remaining_contacts = g_list_reverse (remaining_contacts);
- for (i = remaining_cards; i != NULL; i = g_list_next (i)) {
- ECard *this_card = E_CARD (i->data);
- ECardMatchType this_match = e_card_compare (info->card, this_card);
+ for (i = remaining_contacts; i != NULL; i = g_list_next (i)) {
+ EContact *this_contact = E_CONTACT (i->data);
+ EABContactMatchType this_match = eab_contact_compare (info->contact, this_contact);
if ((gint)this_match > (gint)best_match) {
best_match = this_match;
- best_card = this_card;
+ best_contact = this_contact;
}
}
- g_list_free (remaining_cards);
+ g_list_free (remaining_contacts);
- info->cb (info->card, best_card, best_match, info->closure);
+ info->cb (info->contact, best_contact, best_match, info->closure);
match_search_info_free (info);
}
@@ -587,37 +612,39 @@ static void
use_common_book_cb (EBook *book, gpointer closure)
{
MatchSearchInfo *info = (MatchSearchInfo *) closure;
- ECard *card = info->card;
+ EContact *contact = info->contact;
+ EContactName *contact_name;
+ GList *contact_email;
gchar *query_parts[MAX_QUERY_PARTS];
gint p=0;
gchar *query, *qj;
int i;
if (book == NULL) {
- info->cb (info->card, NULL, E_CARD_MATCH_NONE, info->closure);
+ info->cb (info->contact, NULL, EAB_CONTACT_MATCH_NONE, info->closure);
match_search_info_free (info);
return;
}
-#if 0
- if (card->nickname && *card->nickname)
- query_parts[p++] = g_strdup_printf ("(beginswith \"nickname\" \"%s\")", card->nickname);
-#endif
+ contact_name = e_contact_get (contact, E_CONTACT_NAME);
+ if (contact_name) {
+ if (contact_name->given && *contact_name->given)
+ query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", contact_name->given);
- if (card->name->given && strlen (card->name->given) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->given);
+ if (contact_name->additional && *contact_name->additional)
+ query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", contact_name->additional);
- if (card->name->additional && strlen (card->name->additional) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->additional);
+ if (contact_name->family && *contact_name->family)
+ query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", contact_name->family);
- if (card->name->family && strlen (card->name->family) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->family);
+ e_contact_name_free (contact_name);
+ }
-
- if (card->email) {
- EIterator *iter = e_list_get_iterator (card->email);
- while (e_iterator_is_valid (iter) && p < MAX_QUERY_PARTS) {
- gchar *addr = g_strdup (e_iterator_get (iter));
+ contact_email = e_contact_get (contact, E_CONTACT_EMAIL);
+ if (contact_email) {
+ GList *iter;
+ for (iter = contact_email; iter && p < MAX_QUERY_PARTS; iter = iter->next) {
+ gchar *addr = g_strdup (iter->data);
if (addr && *addr) {
gchar *s = addr;
while (*s) {
@@ -630,10 +657,10 @@ use_common_book_cb (EBook *book, gpointer closure)
query_parts[p++] = g_strdup_printf ("(beginswith \"email\" \"%s\")", addr);
g_free (addr);
}
- e_iterator_next (iter);
}
}
-
+ g_list_foreach (contact_email, (GFunc)g_free, NULL);
+ g_list_free (contact_email);
/* Build up our full query from the parts. */
@@ -648,51 +675,54 @@ use_common_book_cb (EBook *book, gpointer closure)
query = qj;
}
- e_book_simple_query (book, query, simple_query_cb, info);
+ if (query && *query)
+ e_book_async_get_contacts (book, query, query_cb, info);
+ else
+ query_cb (book, E_BOOK_ERROR_OK, NULL, info);
g_free (query);
}
void
-e_card_locate_match (ECard *card, ECardMatchQueryCallback cb, gpointer closure)
+eab_contact_locate_match (EContact *contact, EABContactMatchQueryCallback cb, gpointer closure)
{
MatchSearchInfo *info;
- g_return_if_fail (card && E_IS_CARD (card));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
g_return_if_fail (cb != NULL);
info = g_new (MatchSearchInfo, 1);
- info->card = card;
- g_object_ref (card);
+ info->contact = contact;
+ g_object_ref (contact);
info->cb = cb;
info->closure = closure;
info->avoid = NULL;
- e_book_use_default_book (use_common_book_cb, info);
+ addressbook_load_default_book (use_common_book_cb, info);
}
/**
- * e_card_locate_match_full:
+ * e_contact_locate_match_full:
* @book: The book to look in. If this is NULL, use the default
* addressbook.
- * @card: The card to compare to.
- * @avoid: A list of cards to not match. These will not show up in the search.
+ * @contact: The contact to compare to.
+ * @avoid: A list of contacts to not match. These will not show up in the search.
* @cb: The function to call.
* @closure: The closure to add to the call.
*
- * Look for the best match and return it using the ECardMatchQueryCallback.
+ * Look for the best match and return it using the EABContactMatchQueryCallback.
**/
void
-e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQueryCallback cb, gpointer closure)
+eab_contact_locate_match_full (EBook *book, EContact *contact, GList *avoid, EABContactMatchQueryCallback cb, gpointer closure)
{
MatchSearchInfo *info;
- g_return_if_fail (card && E_IS_CARD (card));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
g_return_if_fail (cb != NULL);
info = g_new (MatchSearchInfo, 1);
- info->card = card;
- g_object_ref (card);
+ info->contact = contact;
+ g_object_ref (contact);
info->cb = cb;
info->closure = closure;
info->avoid = g_list_copy (avoid);
@@ -701,6 +731,6 @@ e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQuer
if (book)
use_common_book_cb (book, info);
else
- e_book_use_default_book (use_common_book_cb, info);
+ addressbook_load_default_book (use_common_book_cb, info);
}
diff --git a/addressbook/gui/merging/eab-contact-compare.h b/addressbook/gui/merging/eab-contact-compare.h
new file mode 100644
index 0000000000..07a9cd7e35
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-compare.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * eab-contact-compare.h
+ *
+ * Copyright (C) 2001,2002,2003 Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#ifndef __EAB_CONTACT_COMPARE_H__
+#define __EAB_CONTACT_COMPARE_H__
+
+#include "ebook/e-book.h"
+#include "ebook/e-contact.h"
+
+typedef enum {
+ EAB_CONTACT_MATCH_NOT_APPLICABLE = 0,
+ EAB_CONTACT_MATCH_NONE = 1,
+ EAB_CONTACT_MATCH_VAGUE = 2,
+ EAB_CONTACT_MATCH_PARTIAL = 3,
+ EAB_CONTACT_MATCH_EXACT = 4
+} EABContactMatchType;
+
+typedef enum {
+ EAB_CONTACT_MATCH_PART_NOT_APPLICABLE = -1,
+ EAB_CONTACT_MATCH_PART_NONE = 0,
+ EAB_CONTACT_MATCH_PART_GIVEN_NAME = 1<<0,
+ EAB_CONTACT_MATCH_PART_ADDITIONAL_NAME = 1<<2,
+ EAB_CONTACT_MATCH_PART_FAMILY_NAME = 1<<3
+} EABContactMatchPart;
+
+typedef void (*EABContactMatchQueryCallback) (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure);
+
+EABContactMatchType eab_contact_compare_name_to_string (EContact *contact, const gchar *str);
+
+EABContactMatchType eab_contact_compare_name_to_string_full (EContact *contact, const gchar *str,
+ gboolean allow_partial_matches,
+ gint *matched_parts, EABContactMatchPart *first_matched_part,
+ gint *matched_character_count);
+
+EABContactMatchType eab_contact_compare_name (EContact *contact1, EContact *contact2);
+EABContactMatchType eab_contact_compare_nickname (EContact *contact1, EContact *contact2);
+EABContactMatchType eab_contact_compare_email (EContact *contact1, EContact *contact2);
+EABContactMatchType eab_contact_compare_address (EContact *contact1, EContact *contact2);
+EABContactMatchType eab_contact_compare_telephone (EContact *contact1, EContact *contact2);
+
+EABContactMatchType eab_contact_compare (EContact *contact1, EContact *contact2);
+
+void eab_contact_locate_match (EContact *contact, EABContactMatchQueryCallback cb, gpointer closure);
+void eab_contact_locate_match_full (EBook *book, EContact *contact, GList *avoid, EABContactMatchQueryCallback cb, gpointer closure);
+
+
+
+#endif /* __E_CONTACT_COMPARE_H__ */
+
diff --git a/addressbook/gui/merging/e-card-duplicate-detected.glade b/addressbook/gui/merging/eab-contact-duplicate-detected.glade
index 5c287cd163..c44547fb92 100644
--- a/addressbook/gui/merging/e-card-duplicate-detected.glade
+++ b/addressbook/gui/merging/eab-contact-duplicate-detected.glade
@@ -68,12 +68,12 @@
<property name="column_spacing">6</property>
<child>
- <widget class="Custom" id="custom-old-card">
+ <widget class="Custom" id="custom-old-contact">
<property name="visible">True</property>
- <property name="creation_function">e_card_merging_create_old_card</property>
+ <property name="creation_function">_eab_contact_merging_create_contact_display</property>
<property name="int1">0</property>
<property name="int2">0</property>
- <property name="last_modification_time">Fri, 08 Jun 2001 01:33:22 GMT</property>
+ <property name="last_modification_time">Sun, 05 Oct 2003 03:55:10 GMT</property>
</widget>
<packing>
<property name="left_attach">1</property>
@@ -155,12 +155,12 @@ in this folder. Would you like to add it anyway?</property>
</child>
<child>
- <widget class="Custom" id="custom-new-card">
+ <widget class="Custom" id="custom-new-contact">
<property name="visible">True</property>
- <property name="creation_function">e_card_merging_create_old_card</property>
+ <property name="creation_function">_eab_contact_merging_create_contact_display</property>
<property name="int1">0</property>
<property name="int2">0</property>
- <property name="last_modification_time">Fri, 08 Jun 2001 01:33:22 GMT</property>
+ <property name="last_modification_time">Sun, 05 Oct 2003 03:54:50 GMT</property>
</widget>
<packing>
<property name="left_attach">1</property>
diff --git a/addressbook/gui/merging/eab-contact-merging.c b/addressbook/gui/merging/eab-contact-merging.c
new file mode 100644
index 0000000000..38a3c188b2
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-merging.c
@@ -0,0 +1,197 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Code for checking for duplicates when doing EContact work.
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 2001, 2002, 2003, Ximian, Inc.
+ */
+
+#include <config.h>
+
+#include "eab-contact-merging.h"
+#include "eab-contact-compare.h"
+#include <glade/glade.h>
+#include <gtk/gtksignal.h>
+#include "addressbook/gui/widgets/eab-contact-display.h"
+
+typedef enum {
+ E_CONTACT_MERGING_ADD,
+ E_CONTACT_MERGING_COMMIT
+} EContactMergingOpType;
+
+typedef struct {
+ EContactMergingOpType op;
+ EBook *book;
+ EContact *contact;
+ EBookIdCallback id_cb;
+ EBookCallback cb;
+ gpointer closure;
+} EContactMergingLookup;
+
+static void
+free_lookup (EContactMergingLookup *lookup)
+{
+ g_object_unref (lookup->book);
+ g_object_unref (lookup->contact);
+
+ g_free (lookup);
+}
+
+static void
+final_id_cb (EBook *book, EBookStatus status, const char *id, gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if (lookup->id_cb)
+ lookup->id_cb (lookup->book, status, id, lookup->closure);
+
+ free_lookup (lookup);
+}
+
+static void
+final_cb (EBook *book, EBookStatus status, gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if (lookup->cb)
+ lookup->cb (lookup->book, status, lookup->closure);
+
+ free_lookup (lookup);
+}
+
+static void
+doit (EContactMergingLookup *lookup)
+{
+ if (lookup->op == E_CONTACT_MERGING_ADD)
+ e_book_async_add_contact (lookup->book, lookup->contact, final_id_cb, lookup);
+ else if (lookup->op == E_CONTACT_MERGING_COMMIT)
+ e_book_async_commit_contact (lookup->book, lookup->contact, final_cb, lookup);
+}
+
+static void
+cancelit (EContactMergingLookup *lookup)
+{
+ if (lookup->op == E_CONTACT_MERGING_ADD) {
+ if (lookup->id_cb)
+ final_id_cb (lookup->book, E_BOOK_ERROR_CANCELLED, NULL, lookup);
+ } else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
+ if (lookup->cb)
+ final_cb (lookup->book, E_BOOK_ERROR_CANCELLED, lookup);
+ }
+}
+
+static void
+response (GtkWidget *dialog, int response, EContactMergingLookup *lookup)
+{
+ gtk_widget_destroy (dialog);
+
+ switch (response) {
+ case 0:
+ doit (lookup);
+ break;
+ case 1:
+ cancelit (lookup);
+ break;
+ }
+}
+
+static void
+match_query_callback (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if ((gint) type <= (gint) EAB_CONTACT_MATCH_VAGUE) {
+ doit (lookup);
+ } else {
+ GladeXML *ui;
+
+ GtkWidget *widget;
+
+ if (lookup->op == E_CONTACT_MERGING_ADD)
+ ui = glade_xml_new (EVOLUTION_GLADEDIR "/eab-contact-duplicate-detected.glade", NULL, NULL);
+ else if (lookup->op == E_CONTACT_MERGING_COMMIT)
+ ui = glade_xml_new (EVOLUTION_GLADEDIR "/eab-contact-merging-commit-duplicate-detected.glade", NULL, NULL);
+ else {
+ doit (lookup);
+ return;
+ }
+
+ widget = glade_xml_get_widget (ui, "custom-old-contact");
+ eab_contact_display_render (EAB_CONTACT_DISPLAY (widget),
+ match, EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+
+ widget = glade_xml_get_widget (ui, "custom-new-contact");
+ eab_contact_display_render (EAB_CONTACT_DISPLAY (widget),
+ contact, EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+
+ widget = glade_xml_get_widget (ui, "dialog-duplicate-contact");
+
+ g_signal_connect (widget, "response",
+ G_CALLBACK (response), lookup);
+
+ gtk_widget_show_all (widget);
+ }
+}
+
+gboolean
+eab_merging_book_add_contact (EBook *book,
+ EContact *contact,
+ EBookIdCallback cb,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup;
+
+ lookup = g_new (EContactMergingLookup, 1);
+
+ lookup->op = E_CONTACT_MERGING_ADD;
+ lookup->book = g_object_ref (book);
+ lookup->contact = g_object_ref (contact);
+ lookup->id_cb = cb;
+ lookup->closure = closure;
+
+ eab_contact_locate_match_full (book, contact, NULL, match_query_callback, lookup);
+
+ return TRUE;
+}
+
+gboolean
+eab_merging_book_commit_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup;
+ GList *avoid;
+
+ lookup = g_new (EContactMergingLookup, 1);
+
+ lookup->op = E_CONTACT_MERGING_COMMIT;
+ lookup->book = g_object_ref (book);
+ lookup->contact = g_object_ref (contact);
+ lookup->cb = cb;
+ lookup->closure = closure;
+
+ avoid = g_list_append (NULL, contact);
+
+ eab_contact_locate_match_full (book, contact, avoid, match_query_callback, lookup);
+
+ g_list_free (avoid);
+
+ return TRUE;
+}
+
+GtkWidget *
+_eab_contact_merging_create_contact_display(gchar *name,
+ gchar *string1, gchar *string2,
+ gint int1, gint int2);
+
+GtkWidget *
+_eab_contact_merging_create_contact_display(gchar *name,
+ gchar *string1, gchar *string2,
+ gint int1, gint int2)
+{
+ return eab_contact_display_new();
+}
diff --git a/addressbook/gui/merging/eab-contact-merging.h b/addressbook/gui/merging/eab-contact-merging.h
new file mode 100644
index 0000000000..6011263f31
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-merging.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * The Evolution addressbook client object.
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 2001, 2002, 2003 Ximian, Inc.
+ */
+
+#ifndef __E_CONTACT_MERGING_H__
+#define __E_CONTACT_MERGING_H__
+
+#include <addressbook/backend/ebook/e-book-async.h>
+
+G_BEGIN_DECLS
+
+gboolean eab_merging_book_add_contact (EBook *book,
+ EContact *contact,
+ EBookIdCallback cb,
+ gpointer closure);
+gboolean eab_merging_book_commit_contact (EBook *book,
+ EContact *contact,
+ EBookCallback cb,
+ gpointer closure);
+
+G_END_DECLS
+
+#endif /* ! __EAB_CONTACT_MERGING_H__ */
diff --git a/addressbook/gui/search/e-addressbook-search-dialog.c b/addressbook/gui/search/e-addressbook-search-dialog.c
index eefd170a73..a8621bf5a7 100644
--- a/addressbook/gui/search/e-addressbook-search-dialog.c
+++ b/addressbook/gui/search/e-addressbook-search-dialog.c
@@ -30,23 +30,23 @@
#include "e-addressbook-search-dialog.h"
-static void e_addressbook_search_dialog_init (EAddressbookSearchDialog *widget);
-static void e_addressbook_search_dialog_class_init (EAddressbookSearchDialogClass *klass);
-static void e_addressbook_search_dialog_dispose (GObject *object);
+static void eab_search_dialog_init (EABSearchDialog *widget);
+static void eab_search_dialog_class_init (EABSearchDialogClass *klass);
+static void eab_search_dialog_dispose (GObject *object);
static GtkDialog *parent_class = NULL;
#define PARENT_TYPE GTK_TYPE_DIALOG
-E_MAKE_TYPE (e_addressbook_search_dialog,
- "EAddressbookSearchDialog",
- EAddressbookSearchDialog,
- e_addressbook_search_dialog_class_init,
- e_addressbook_search_dialog_init,
+E_MAKE_TYPE (eab_search_dialog,
+ "EABSearchDialog",
+ EABSearchDialog,
+ eab_search_dialog_class_init,
+ eab_search_dialog_init,
PARENT_TYPE)
static void
-e_addressbook_search_dialog_class_init (EAddressbookSearchDialogClass *klass)
+eab_search_dialog_class_init (EABSearchDialogClass *klass)
{
GObjectClass *object_class;
@@ -54,11 +54,11 @@ e_addressbook_search_dialog_class_init (EAddressbookSearchDialogClass *klass)
parent_class = g_type_class_ref (PARENT_TYPE);
- object_class->dispose = e_addressbook_search_dialog_dispose;
+ object_class->dispose = eab_search_dialog_dispose;
}
static GtkWidget *
-get_widget (EAddressbookSearchDialog *view)
+get_widget (EABSearchDialog *view)
{
FilterPart *part;
@@ -79,7 +79,7 @@ get_widget (EAddressbookSearchDialog *view)
}
static char *
-get_query (EAddressbookSearchDialog *view)
+get_query (EABSearchDialog *view)
{
GString *out = g_string_new("");
char *ret;
@@ -92,7 +92,7 @@ get_query (EAddressbookSearchDialog *view)
}
static void
-dialog_response (GtkWidget *widget, int response_id, EAddressbookSearchDialog *dialog)
+dialog_response (GtkWidget *widget, int response_id, EABSearchDialog *dialog)
{
char *query;
@@ -108,7 +108,7 @@ dialog_response (GtkWidget *widget, int response_id, EAddressbookSearchDialog *d
}
static void
-e_addressbook_search_dialog_init (EAddressbookSearchDialog *view)
+eab_search_dialog_init (EABSearchDialog *view)
{
GtkDialog *dialog = GTK_DIALOG (view);
@@ -131,19 +131,19 @@ e_addressbook_search_dialog_init (EAddressbookSearchDialog *view)
}
GtkWidget *
-e_addressbook_search_dialog_new (EAddressbookView *addr_view)
+eab_search_dialog_new (EABView *addr_view)
{
- EAddressbookSearchDialog *view = g_object_new (E_ADDRESSBOOK_SEARCH_DIALOG_TYPE, NULL);
+ EABSearchDialog *view = g_object_new (EAB_SEARCH_DIALOG_TYPE, NULL);
view->view = addr_view;
return GTK_WIDGET(view);
}
static void
-e_addressbook_search_dialog_dispose (GObject *object)
+eab_search_dialog_dispose (GObject *object)
{
- EAddressbookSearchDialog *view;
+ EABSearchDialog *view;
- view = E_ADDRESSBOOK_SEARCH_DIALOG (object);
+ view = EAB_SEARCH_DIALOG (object);
if (view->context) {
g_object_unref(view->context);
diff --git a/addressbook/gui/search/e-addressbook-search-dialog.h b/addressbook/gui/search/e-addressbook-search-dialog.h
index 4be0050ca0..ef501766ea 100644
--- a/addressbook/gui/search/e-addressbook-search-dialog.h
+++ b/addressbook/gui/search/e-addressbook-search-dialog.h
@@ -17,8 +17,9 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-#ifndef __E_ADDRESSBOOK_SEARCH_DIALOG_H__
-#define __E_ADDRESSBOOK_SEARCH_DIALOG_H__
+
+#ifndef __EAB_SEARCH_DIALOG_H__
+#define __EAB_SEARCH_DIALOG_H__
#include <ebook/e-book.h>
@@ -29,37 +30,37 @@
G_BEGIN_DECLS
-#define E_ADDRESSBOOK_SEARCH_DIALOG_TYPE (e_addressbook_search_dialog_get_type ())
-#define E_ADDRESSBOOK_SEARCH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE, EAddressbookSearchDialog))
-#define E_ADDRESSBOOK_SEARCH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE, EAddressbookSearchDialogClass))
-#define E_IS_ADDRESSBOOK_SEARCH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE))
-#define E_IS_ADDRESSBOOK_SEARCH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE))
+#define EAB_SEARCH_DIALOG_TYPE (eab_search_dialog_get_type ())
+#define EAB_SEARCH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EAB_SEARCH_DIALOG_TYPE, EABSearchDialog))
+#define EAB_SEARCH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EAB_SEARCH_DIALOG_TYPE, EABSearchDialogClass))
+#define E_IS_ADDRESSBOOK_SEARCH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EAB_SEARCH_DIALOG_TYPE))
+#define E_IS_ADDRESSBOOK_SEARCH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EAB_SEARCH_DIALOG_TYPE))
-typedef struct _EAddressbookSearchDialog EAddressbookSearchDialog;
-typedef struct _EAddressbookSearchDialogClass EAddressbookSearchDialogClass;
+typedef struct _EABSearchDialog EABSearchDialog;
+typedef struct _EABSearchDialogClass EABSearchDialogClass;
-struct _EAddressbookSearchDialog
+struct _EABSearchDialog
{
GtkDialog parent;
GtkWidget *search;
- EAddressbookView *view;
+ EABView *view;
RuleContext *context;
FilterRule *rule;
};
-struct _EAddressbookSearchDialogClass
+struct _EABSearchDialogClass
{
GtkDialogClass parent_class;
};
-GType e_addressbook_search_dialog_get_type (void);
+GType eab_search_dialog_get_type (void);
-GtkWidget *e_addressbook_search_dialog_new (EAddressbookView *view);
+GtkWidget *eab_search_dialog_new (EABView *view);
G_END_DECLS
-#endif /* __E_ADDRESSBOOK_SEARCH_DIALOG_H__ */
+#endif /* __EAB_SEARCH_DIALOG_H__ */
diff --git a/addressbook/gui/widgets/.cvsignore b/addressbook/gui/widgets/.cvsignore
index d3b9ac4305..b67f65e6c3 100644
--- a/addressbook/gui/widgets/.cvsignore
+++ b/addressbook/gui/widgets/.cvsignore
@@ -10,8 +10,8 @@ minicard-test
minicard-view-test
minicard-widget-test
reflow-test
-e-addressbook-marshal.c
-e-addressbook-marshal.h
+eab-marshal.c
+eab-marshal.h
Evolution-Composer-stubs.c
Evolution-Composer-skels.c
Evolution-Composer-common.c
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index 2185d10764..ce441cbafb 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -1,9 +1,10 @@
INCLUDES = \
- -DG_LOG_DOMAIN=\"e-minicard\" \
+ -DG_LOG_DOMAIN=\"eab-widgets\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
-DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \
-DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook \
-I$(top_srcdir)/addressbook/backend \
-I$(top_builddir)/addressbook/backend \
-I$(top_srcdir)/addressbook/gui/contact-editor \
@@ -35,37 +36,39 @@ CORBA_SOURCE_C = $(CORBA_COMPOSER_SOURCE_C)
CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C)
noinst_LTLIBRARIES = \
- libeminicard.la
+ libeabwidgets.la
-libeminicard_la_SOURCES = \
+libeabwidgets_la_SOURCES = \
$(CORBA_SOURCE) \
- e-addressbook-marshal.c \
+ eab-contact-display.c \
+ eab-contact-display.h \
+ eab-gui-util.c \
+ eab-gui-util.h \
+ eab-popup-control.c \
+ eab-popup-control.h \
+ eab-vcard-control.c \
+ eab-vcard-control.h \
+ eab-marshal.c \
+ e-minicard.c \
+ e-minicard.h \
+ e-minicard-label.c \
+ e-minicard-label.h \
+ e-minicard-view.c \
+ e-minicard-view.h \
+ e-minicard-view-widget.c \
+ e-minicard-view-widget.h \
e-addressbook-reflow-adapter.c \
e-addressbook-reflow-adapter.h \
e-addressbook-table-adapter.c \
e-addressbook-table-adapter.h \
e-addressbook-model.c \
e-addressbook-model.h \
- e-addressbook-util.c \
- e-addressbook-util.h \
e-addressbook-view.c \
e-addressbook-view.h \
- e-minicard-control.c \
- e-minicard-control.h \
- e-minicard-label.c \
- e-minicard-label.h \
- e-minicard-view-widget.c \
- e-minicard-view-widget.h \
- e-minicard-view.c \
- e-minicard-view.h \
- e-minicard-widget.c \
- e-minicard-widget.h \
- e-minicard.c \
- e-minicard.h \
- gal-view-factory-minicard.c \
- gal-view-factory-minicard.h \
gal-view-minicard.c \
- gal-view-minicard.h
+ gal-view-minicard.h \
+ gal-view-factory-minicard.c \
+ gal-view-factory-minicard.h
#TREEVIEW_SOURCES= e-addressbook-treeview-adapter.c \
# e-addressbook-treeview-adapter.h \
@@ -74,7 +77,7 @@ libeminicard_la_SOURCES = \
# gal-view-treeview.c \
# gal-view-treeview.h
-MARSHAL_GENERATED = e-addressbook-marshal.c e-addressbook-marshal.h
+MARSHAL_GENERATED = eab-marshal.c eab-marshal.h
@EVO_MARSHAL_RULE@
BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED)
@@ -83,74 +86,8 @@ CLEANFILES = $(BUILT_SOURCES)
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
-#noinst_PROGRAMS = \
-# minicard-widget-test \
-# minicard-label-test \
-# minicard-test
-## reflow-test
-## minicard-view-test
-#
-#minicard_label_test_SOURCES = \
-# test-minicard-label.c
-#
-#minicard_label_test_LDADD = \
-# libeminicard.a \
-# $(EVOLUTION_ADDRESSBOOK_LIBS) \
-# $(top_builddir)/e-util/libeutil.la
-#
-#minicard_test_SOURCES = \
-# test-minicard.c
-#
-#minicard_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.la \
-# $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
-# $(EVOLUTION_ADDRESSBOOK_LIBS) \
-# libeminicard.a
-#
-#reflow_test_SOURCES = \
-# test-reflow.c
-#
-#reflow_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.la \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
-
-#minicard_view_test_SOURCES = \
-# test-minicard-view.c
-
-#minicard_view_test_LDADD = \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.la
-#
-#minicard_widget_test_SOURCES = \
-# e-minicard-widget-test.c
-#
-#minicard_widget_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.a \
-# $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.la \
-# $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
-
etspec_DATA= e-addressbook-view.etspec
EXTRA_DIST = \
$(etspec_DATA) \
- e-addressbook-marshal.list
+ eab-marshal.list
diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c
index 10af915ecf..e8a1e76a38 100644
--- a/addressbook/gui/widgets/e-addressbook-model.c
+++ b/addressbook/gui/widgets/e-addressbook-model.c
@@ -8,25 +8,24 @@
*/
#include <config.h>
-#include "e-addressbook-marshal.h"
+#include "eab-marshal.h"
#include "e-addressbook-model.h"
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
#include <gnome.h>
#include <gal/widgets/e-gui-utils.h>
-#include "e-addressbook-util.h"
-#include "e-addressbook-marshal.h"
+#include "eab-gui-util.h"
#define PARENT_TYPE G_TYPE_OBJECT
static GObjectClass *parent_class;
/*
- * EAddressbookModel callbacks
+ * EABModel callbacks
* These are the callbacks that define the behavior of our custom model.
*/
-static void e_addressbook_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_addressbook_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
enum {
@@ -42,21 +41,19 @@ enum {
SEARCH_STARTED,
SEARCH_RESULT,
FOLDER_BAR_MESSAGE,
- CARD_ADDED,
- CARD_REMOVED,
- CARD_CHANGED,
+ CONTACT_ADDED,
+ CONTACT_REMOVED,
+ CONTACT_CHANGED,
MODEL_CHANGED,
STOP_STATE_CHANGED,
BACKEND_DIED,
LAST_SIGNAL
};
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
-
-static guint e_addressbook_model_signals [LAST_SIGNAL] = {0, };
+static guint eab_model_signals [LAST_SIGNAL] = {0, };
static void
-free_data (EAddressbookModel *model)
+free_data (EABModel *model)
{
if (model->data) {
int i;
@@ -73,17 +70,17 @@ free_data (EAddressbookModel *model)
}
static void
-remove_book_view(EAddressbookModel *model)
+remove_book_view(EABModel *model)
{
- if (model->book_view && model->create_card_id)
+ if (model->book_view && model->create_contact_id)
g_signal_handler_disconnect (model->book_view,
- model->create_card_id);
- if (model->book_view && model->remove_card_id)
+ model->create_contact_id);
+ if (model->book_view && model->remove_contact_id)
g_signal_handler_disconnect (model->book_view,
- model->remove_card_id);
- if (model->book_view && model->modify_card_id)
+ model->remove_contact_id);
+ if (model->book_view && model->modify_contact_id)
g_signal_handler_disconnect (model->book_view,
- model->modify_card_id);
+ model->modify_contact_id);
if (model->book_view && model->status_message_id)
g_signal_handler_disconnect (model->book_view,
model->status_message_id);
@@ -91,9 +88,9 @@ remove_book_view(EAddressbookModel *model)
g_signal_handler_disconnect (model->book_view,
model->sequence_complete_id);
- model->create_card_id = 0;
- model->remove_card_id = 0;
- model->modify_card_id = 0;
+ model->create_contact_id = 0;
+ model->remove_contact_id = 0;
+ model->modify_contact_id = 0;
model->status_message_id = 0;
model->sequence_complete_id = 0;
@@ -109,12 +106,7 @@ remove_book_view(EAddressbookModel *model)
static void
addressbook_dispose(GObject *object)
{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
-
- if (model->get_view_idle) {
- g_source_remove(model->get_view_idle);
- model->get_view_idle = 0;
- }
+ EABModel *model = EAB_MODEL(object);
remove_book_view(model);
free_data (model);
@@ -135,7 +127,7 @@ addressbook_dispose(GObject *object)
}
if (model->query) {
- g_free (model->query);
+ e_book_query_unref (model->query);
model->query = NULL;
}
@@ -144,7 +136,7 @@ addressbook_dispose(GObject *object)
}
static void
-update_folder_bar_message (EAddressbookModel *model)
+update_folder_bar_message (EABModel *model)
{
int count;
char *message;
@@ -153,67 +145,68 @@ update_folder_bar_message (EAddressbookModel *model)
switch (count) {
case 0:
- message = g_strdup (_("No cards"));
+ message = g_strdup (_("No contacts"));
break;
case 1:
- message = g_strdup (_("1 card"));
+ message = g_strdup (_("1 contact"));
break;
default:
- message = g_strdup_printf (_("%d cards"), count);
+ message = g_strdup_printf (_("%d contacts"), count);
break;
}
g_signal_emit (model,
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE], 0,
+ eab_model_signals [FOLDER_BAR_MESSAGE], 0,
message);
g_free (message);
}
static void
-create_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
+create_contact(EBookView *book_view,
+ const GList *contacts,
+ EABModel *model)
{
int old_count = model->data_count;
- int length = g_list_length ((GList *)cards);
+ int length = g_list_length ((GList *)contacts);
if (model->data_count + length > model->allocated_count) {
while (model->data_count + length > model->allocated_count)
model->allocated_count = model->allocated_count * 2 + 1;
- model->data = g_renew(ECard *, model->data, model->allocated_count);
+ model->data = g_renew(EContact *, model->data, model->allocated_count);
}
- for ( ; cards; cards = cards->next) {
- model->data[model->data_count++] = cards->data;
- g_object_ref (cards->data);
+ for ( ; contacts; contacts = contacts->next) {
+ model->data[model->data_count++] = contacts->data;
+ g_object_ref (contacts->data);
}
g_signal_emit (model,
- e_addressbook_model_signals [CARD_ADDED], 0,
+ eab_model_signals [CONTACT_ADDED], 0,
old_count, model->data_count - old_count);
update_folder_bar_message (model);
}
static void
-remove_card(EBookView *book_view,
- GList *ids,
- EAddressbookModel *model)
+remove_contact(EBookView *book_view,
+ GList *ids,
+ EABModel *model)
{
+ /* XXX we should keep a hash around instead of this O(n*m) loop */
int i = 0;
GList *l;
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) ) {
+ if ( !strcmp(e_contact_get_const (model->data[i], E_CONTACT_UID), id) ) {
g_object_unref (model->data[i]);
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
+ memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (EContact *));
model->data_count--;
g_signal_emit (model,
- e_addressbook_model_signals [CARD_REMOVED], 0,
+ eab_model_signals [CONTACT_REMOVED], 0,
i);
break;
@@ -225,18 +218,19 @@ remove_card(EBookView *book_view,
}
static void
-modify_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
+modify_contact(EBookView *book_view,
+ const GList *contacts,
+ EABModel *model)
{
- for ( ; cards; cards = cards->next) {
+ for ( ; contacts; contacts = contacts->next) {
int i;
for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_get_id(model->data[i]), e_card_get_id(E_CARD(cards->data))) ) {
+ if ( !strcmp(e_contact_get_const(model->data[i], E_CONTACT_UID),
+ e_contact_get_const(E_CONTACT(contacts->data), E_CONTACT_UID)) ) {
g_object_unref (model->data[i]);
- model->data[i] = e_card_duplicate(E_CARD(cards->data));
+ model->data[i] = e_contact_duplicate(E_CONTACT(contacts->data));
g_signal_emit (model,
- e_addressbook_model_signals [CARD_CHANGED], 0,
+ eab_model_signals [CONTACT_CHANGED], 0,
i);
break;
}
@@ -247,57 +241,57 @@ modify_card(EBookView *book_view,
static void
status_message (EBookView *book_view,
char* status,
- EAddressbookModel *model)
+ EABModel *model)
{
g_signal_emit (model,
- e_addressbook_model_signals [STATUS_MESSAGE], 0,
+ eab_model_signals [STATUS_MESSAGE], 0,
status);
}
static void
sequence_complete (EBookView *book_view,
EBookViewStatus status,
- EAddressbookModel *model)
+ EABModel *model)
{
model->search_in_progress = FALSE;
status_message (book_view, NULL, model);
g_signal_emit (model,
- e_addressbook_model_signals [SEARCH_RESULT], 0,
+ eab_model_signals [SEARCH_RESULT], 0,
status);
g_signal_emit (model,
- e_addressbook_model_signals [STOP_STATE_CHANGED], 0);
+ eab_model_signals [STOP_STATE_CHANGED], 0);
}
static void
writable_status (EBook *book,
gboolean writable,
- EAddressbookModel *model)
+ EABModel *model)
{
if (!model->editable_set) {
model->editable = writable;
g_signal_emit (model,
- e_addressbook_model_signals [WRITABLE_STATUS], 0,
+ eab_model_signals [WRITABLE_STATUS], 0,
writable);
}
}
static void
backend_died (EBook *book,
- EAddressbookModel *model)
+ EABModel *model)
{
g_signal_emit (model,
- e_addressbook_model_signals [BACKEND_DIED], 0);
+ eab_model_signals [BACKEND_DIED], 0);
}
static void
-e_addressbook_model_class_init (GObjectClass *object_class)
+eab_model_class_init (GObjectClass *object_class)
{
parent_class = g_type_class_ref (PARENT_TYPE);
object_class->dispose = addressbook_dispose;
- object_class->set_property = e_addressbook_model_set_property;
- object_class->get_property = e_addressbook_model_get_property;
+ object_class->set_property = eab_model_set_property;
+ object_class->get_property = eab_model_get_property;
g_object_class_install_property (object_class, PROP_BOOK,
g_param_spec_object ("book",
@@ -320,119 +314,118 @@ e_addressbook_model_class_init (GObjectClass *object_class)
FALSE,
G_PARAM_READWRITE));
- e_addressbook_model_signals [WRITABLE_STATUS] =
+ eab_model_signals [WRITABLE_STATUS] =
g_signal_new ("writable_status",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, writable_status),
+ G_STRUCT_OFFSET (EABModelClass, writable_status),
NULL, NULL,
- e_addressbook_marshal_NONE__BOOL,
+ eab_marshal_NONE__BOOL,
G_TYPE_NONE,
1, G_TYPE_BOOLEAN);
- e_addressbook_model_signals [STATUS_MESSAGE] =
+ eab_model_signals [STATUS_MESSAGE] =
g_signal_new ("status_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, status_message),
+ G_STRUCT_OFFSET (EABModelClass, status_message),
NULL, NULL,
- e_addressbook_marshal_NONE__POINTER,
+ eab_marshal_NONE__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);
- e_addressbook_model_signals [SEARCH_STARTED] =
+ eab_model_signals [SEARCH_STARTED] =
g_signal_new ("search_started",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, search_started),
+ G_STRUCT_OFFSET (EABModelClass, search_started),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
- e_addressbook_model_signals [SEARCH_RESULT] =
+ eab_model_signals [SEARCH_RESULT] =
g_signal_new ("search_result",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, search_result),
+ G_STRUCT_OFFSET (EABModelClass, search_result),
NULL, NULL,
- e_addressbook_marshal_NONE__INT,
+ eab_marshal_NONE__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE] =
+ eab_model_signals [FOLDER_BAR_MESSAGE] =
g_signal_new ("folder_bar_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, folder_bar_message),
+ G_STRUCT_OFFSET (EABModelClass, folder_bar_message),
NULL, NULL,
- e_addressbook_marshal_NONE__POINTER,
+ eab_marshal_NONE__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
- e_addressbook_model_signals [CARD_ADDED] =
- g_signal_new ("card_added",
+ eab_model_signals [CONTACT_ADDED] =
+ g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, card_added),
+ G_STRUCT_OFFSET (EABModelClass, contact_added),
NULL, NULL,
- e_addressbook_marshal_NONE__INT_INT,
+ eab_marshal_NONE__INT_INT,
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
- e_addressbook_model_signals [CARD_REMOVED] =
- g_signal_new ("card_removed",
+ eab_model_signals [CONTACT_REMOVED] =
+ g_signal_new ("contact_removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, card_removed),
+ G_STRUCT_OFFSET (EABModelClass, contact_removed),
NULL, NULL,
- e_addressbook_marshal_NONE__INT,
+ eab_marshal_NONE__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- e_addressbook_model_signals [CARD_CHANGED] =
- g_signal_new ("card_changed",
+ eab_model_signals [CONTACT_CHANGED] =
+ g_signal_new ("contact_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, card_changed),
+ G_STRUCT_OFFSET (EABModelClass, contact_changed),
NULL, NULL,
- e_addressbook_marshal_NONE__INT,
+ eab_marshal_NONE__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- e_addressbook_model_signals [MODEL_CHANGED] =
+ eab_model_signals [MODEL_CHANGED] =
g_signal_new ("model_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, model_changed),
+ G_STRUCT_OFFSET (EABModelClass, model_changed),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
- e_addressbook_model_signals [STOP_STATE_CHANGED] =
+ eab_model_signals [STOP_STATE_CHANGED] =
g_signal_new ("stop_state_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, stop_state_changed),
+ G_STRUCT_OFFSET (EABModelClass, stop_state_changed),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
- e_addressbook_model_signals [BACKEND_DIED] =
+ eab_model_signals [BACKEND_DIED] =
g_signal_new ("backend_died",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookModelClass, backend_died),
+ G_STRUCT_OFFSET (EABModelClass, backend_died),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
}
static void
-e_addressbook_model_init (GObject *object)
+eab_model_init (GObject *object)
{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
+ EABModel *model = EAB_MODEL(object);
model->book = NULL;
- model->query = g_strdup("(contains \"x-evolution-any-field\" \"\")");
+ model->query = e_book_query_any_field_contains ("");
model->book_view = NULL;
- model->get_view_idle = 0;
- model->create_card_id = 0;
- model->remove_card_id = 0;
- model->modify_card_id = 0;
+ model->create_contact_id = 0;
+ model->remove_contact_id = 0;
+ model->modify_contact_id = 0;
model->status_message_id = 0;
model->writable_status_id = 0;
model->backend_died_id = 0;
@@ -449,30 +442,28 @@ e_addressbook_model_init (GObject *object)
static void
book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure)
{
- EAddressbookModel *model = closure;
+ EABModel *model = closure;
- remove_book_view(model);
-
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error getting book view"), status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (_("Error getting book view"), status);
return;
}
model->book_view = book_view;
if (model->book_view)
g_object_ref (model->book_view);
- model->create_card_id = g_signal_connect(model->book_view,
- "card_added",
- G_CALLBACK (create_card),
- model);
- model->remove_card_id = g_signal_connect(model->book_view,
- "card_removed",
- G_CALLBACK (remove_card),
- model);
- model->modify_card_id = g_signal_connect(model->book_view,
- "card_changed",
- G_CALLBACK(modify_card),
- model);
+ model->create_contact_id = g_signal_connect(model->book_view,
+ "contacts_added",
+ G_CALLBACK (create_contact),
+ model);
+ model->remove_contact_id = g_signal_connect(model->book_view,
+ "contacts_removed",
+ G_CALLBACK (remove_contact),
+ model);
+ model->modify_contact_id = g_signal_connect(model->book_view,
+ "contacts_changed",
+ G_CALLBACK(modify_contact),
+ model);
model->status_message_id = g_signal_connect(model->book_view,
"status_message",
G_CALLBACK(status_message),
@@ -482,70 +473,65 @@ book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointe
G_CALLBACK(sequence_complete),
model);
- free_data (model);
-
model->search_in_progress = TRUE;
g_signal_emit (model,
- e_addressbook_model_signals [MODEL_CHANGED], 0);
+ eab_model_signals [MODEL_CHANGED], 0);
g_signal_emit (model,
- e_addressbook_model_signals [SEARCH_STARTED], 0);
+ eab_model_signals [SEARCH_STARTED], 0);
g_signal_emit (model,
- e_addressbook_model_signals [STOP_STATE_CHANGED], 0);
+ eab_model_signals [STOP_STATE_CHANGED], 0);
+
+ e_book_view_start (model->book_view);
}
-static gboolean
-get_view (EAddressbookModel *model)
+static void
+get_view (EABModel *model)
{
+ gboolean success;
+
if (model->book && model->query) {
+ char *query_string = e_book_query_to_string (model->query);
+
+ remove_book_view(model);
+ free_data (model);
+
if (model->first_get_view) {
+ model->first_get_view = FALSE;
+
if (e_book_check_static_capability (model->book, "do-initial-query")) {
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
+ success = e_book_async_get_book_view (model->book, query_string, book_view_loaded, model);
} else {
- remove_book_view(model);
- free_data (model);
g_signal_emit (model,
- e_addressbook_model_signals [MODEL_CHANGED], 0);
+ eab_model_signals [MODEL_CHANGED], 0);
g_signal_emit (model,
- e_addressbook_model_signals [STOP_STATE_CHANGED], 0);
+ eab_model_signals [STOP_STATE_CHANGED], 0);
+ g_free (query_string);
+ return;
}
- model->first_get_view = FALSE;
}
else
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
- }
+ success = e_book_async_get_book_view (model->book, query_string, book_view_loaded, model);
- model->get_view_idle = 0;
- return FALSE;
-}
-
-ECard *
-e_addressbook_model_get_card(EAddressbookModel *model,
- int row)
-{
- if (model->data && 0 <= row && row < model->data_count) {
- ECard *card;
- card = e_card_duplicate (model->data[row]);
- return card;
+ g_free (query_string);
}
- return NULL;
}
-const ECard *
-e_addressbook_model_peek_card(EAddressbookModel *model,
- int row)
+EContact *
+eab_model_get_contact(EABModel *model,
+ int row)
{
if (model->data && 0 <= row && row < model->data_count) {
- return model->data[row];
+ return e_contact_duplicate (model->data[row]);
}
return NULL;
}
static void
-e_addressbook_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- EAddressbookModel *model;
+ EABModel *model;
- model = E_ADDRESSBOOK_MODEL (object);
+ model = EAB_MODEL (object);
switch (prop_id){
case PROP_BOOK:
@@ -564,10 +550,11 @@ e_addressbook_model_set_property (GObject *object, guint prop_id, const GValue *
}
model->book = E_BOOK(g_value_get_object (value));
if (model->book) {
+ if (!model->editable_set)
+ model->editable = e_book_is_writable (model->book);
model->first_get_view = TRUE;
g_object_ref (model->book);
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
+ get_view (model);
g_signal_connect (model->book,
"writable_status",
G_CALLBACK (writable_status), model);
@@ -578,10 +565,9 @@ e_addressbook_model_set_property (GObject *object, guint prop_id, const GValue *
break;
case PROP_QUERY:
if (model->query)
- g_free(model->query);
- model->query = g_strdup(g_value_get_string (value));
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
+ e_book_query_unref (model->query);
+ model->query = e_book_query_from_string (g_value_get_string (value));
+ get_view (model);
break;
case PROP_EDITABLE:
model->editable = g_value_get_boolean (value);
@@ -594,21 +580,23 @@ e_addressbook_model_set_property (GObject *object, guint prop_id, const GValue *
}
static void
-e_addressbook_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
- EAddressbookModel *e_addressbook_model;
+ EABModel *eab_model;
- e_addressbook_model = E_ADDRESSBOOK_MODEL (object);
+ eab_model = EAB_MODEL (object);
switch (prop_id) {
case PROP_BOOK:
- g_value_set_object (value, e_addressbook_model->book);
+ g_value_set_object (value, eab_model->book);
break;
- case PROP_QUERY:
- g_value_set_string (value, g_strdup(e_addressbook_model->query));
+ case PROP_QUERY: {
+ char *query_string = e_book_query_to_string (eab_model->query);
+ g_value_set_string (value, query_string);
break;
+ }
case PROP_EDITABLE:
- g_value_set_boolean (value, e_addressbook_model->editable);
+ g_value_set_boolean (value, eab_model->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -617,81 +605,81 @@ e_addressbook_model_get_property (GObject *object, guint prop_id, GValue *value,
}
GType
-e_addressbook_model_get_type (void)
+eab_model_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
- sizeof (EAddressbookModelClass),
+ sizeof (EABModelClass),
NULL, /* base_init */
NULL, /* base_finalize */
- (GClassInitFunc) e_addressbook_model_class_init,
+ (GClassInitFunc) eab_model_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (EAddressbookModel),
+ sizeof (EABModel),
0, /* n_preallocs */
- (GInstanceInitFunc) e_addressbook_model_init,
+ (GInstanceInitFunc) eab_model_init,
};
- type = g_type_register_static (PARENT_TYPE, "EAddressbookModel", &info, 0);
+ type = g_type_register_static (PARENT_TYPE, "EABModel", &info, 0);
}
return type;
}
-EAddressbookModel*
-e_addressbook_model_new (void)
+EABModel*
+eab_model_new (void)
{
- EAddressbookModel *et;
+ EABModel *et;
- et = g_object_new (E_TYPE_ADDRESSBOOK_MODEL, NULL);
+ et = g_object_new (EAB_TYPE_MODEL, NULL);
return et;
}
-void e_addressbook_model_stop (EAddressbookModel *model)
+void eab_model_stop (EABModel *model)
{
remove_book_view(model);
g_signal_emit (model,
- e_addressbook_model_signals [STOP_STATE_CHANGED], 0);
+ eab_model_signals [STOP_STATE_CHANGED], 0);
g_signal_emit (model,
- e_addressbook_model_signals [STATUS_MESSAGE], 0,
+ eab_model_signals [STATUS_MESSAGE], 0,
"Search Interrupted.");
}
gboolean
-e_addressbook_model_can_stop (EAddressbookModel *model)
+eab_model_can_stop (EABModel *model)
{
return model->search_in_progress;
}
void
-e_addressbook_model_force_folder_bar_message (EAddressbookModel *model)
+eab_model_force_folder_bar_message (EABModel *model)
{
update_folder_bar_message (model);
}
int
-e_addressbook_model_card_count (EAddressbookModel *model)
+eab_model_contact_count (EABModel *model)
{
return model->data_count;
}
-ECard *
-e_addressbook_model_card_at (EAddressbookModel *model, int index)
+const EContact *
+eab_model_contact_at (EABModel *model, int index)
{
return model->data[index];
}
gboolean
-e_addressbook_model_editable (EAddressbookModel *model)
+eab_model_editable (EABModel *model)
{
return model->editable;
}
EBook *
-e_addressbook_model_get_ebook (EAddressbookModel *model)
+eab_model_get_ebook (EABModel *model)
{
return model->book;
}
diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h
index 57cfe6f729..35f9d0e87f 100644
--- a/addressbook/gui/widgets/e-addressbook-model.h
+++ b/addressbook/gui/widgets/e-addressbook-model.h
@@ -1,37 +1,34 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_ADDRESSBOOK_MODEL_H_
-#define _E_ADDRESSBOOK_MODEL_H_
+#ifndef _EAB_MODEL_H_
+#define _EAB_MODEL_H_
#include <glib.h>
#include <glib-object.h>
-#include "addressbook/backend/ebook/e-book.h"
+#include "addressbook/backend/ebook/e-book-async.h"
#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-#define E_TYPE_ADDRESSBOOK_MODEL (e_addressbook_model_get_type ())
-#define E_ADDRESSBOOK_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModel))
-#define E_ADDRESSBOOK_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelClass))
-#define E_IS_ADDRESSBOOK_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESSBOOK_MODEL))
-#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESSBOOK_MODEL))
+#define EAB_TYPE_MODEL (eab_model_get_type ())
+#define EAB_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_MODEL, EABModel))
+#define EAB_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EAB_TYPE_MODEL, EABModelClass))
+#define E_IS_ADDRESSBOOK_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_MODEL))
+#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_MODEL))
-typedef struct _EAddressbookModel EAddressbookModel;
-typedef struct _EAddressbookModelClass EAddressbookModelClass;
+typedef struct _EABModel EABModel;
+typedef struct _EABModelClass EABModelClass;
-struct _EAddressbookModel {
+struct _EABModel {
GObject parent;
/* item specific fields */
EBook *book;
- char *query;
+ EBookQuery *query;
EBookView *book_view;
- int get_view_idle;
-
- ECard **data;
+ EContact **data;
int data_count;
int allocated_count;
- int create_card_id, remove_card_id, modify_card_id;
+ int create_contact_id, remove_contact_id, modify_contact_id;
int status_message_id, writable_status_id, sequence_complete_id;
int backend_died_id;
@@ -42,44 +39,42 @@ struct _EAddressbookModel {
};
-struct _EAddressbookModelClass {
+struct _EABModelClass {
GObjectClass parent_class;
/*
* Signals
*/
- void (*writable_status) (EAddressbookModel *model, gboolean writable);
- void (*search_started) (EAddressbookModel *model);
- void (*search_result) (EAddressbookModel *model, EBookViewStatus status);
- void (*status_message) (EAddressbookModel *model, const gchar *message);
- void (*folder_bar_message) (EAddressbookModel *model, const gchar *message);
- void (*card_added) (EAddressbookModel *model, gint index, gint count);
- void (*card_removed) (EAddressbookModel *model, gint index);
- void (*card_changed) (EAddressbookModel *model, gint index);
- void (*model_changed) (EAddressbookModel *model);
- void (*stop_state_changed) (EAddressbookModel *model);
- void (*backend_died) (EAddressbookModel *model);
+ void (*writable_status) (EABModel *model, gboolean writable);
+ void (*search_started) (EABModel *model);
+ void (*search_result) (EABModel *model, EBookViewStatus status);
+ void (*status_message) (EABModel *model, const gchar *message);
+ void (*folder_bar_message) (EABModel *model, const gchar *message);
+ void (*contact_added) (EABModel *model, gint index, gint count);
+ void (*contact_removed) (EABModel *model, gint index);
+ void (*contact_changed) (EABModel *model, gint index);
+ void (*model_changed) (EABModel *model);
+ void (*stop_state_changed) (EABModel *model);
+ void (*backend_died) (EABModel *model);
};
-GType e_addressbook_model_get_type (void);
-EAddressbookModel *e_addressbook_model_new (void);
+GType eab_model_get_type (void);
+EABModel *eab_model_new (void);
/* Returns object with ref count of 1. */
-ECard *e_addressbook_model_get_card (EAddressbookModel *model,
- int row);
-const ECard *e_addressbook_model_peek_card (EAddressbookModel *model,
- int row);
-EBook *e_addressbook_model_get_ebook (EAddressbookModel *model);
+EContact *eab_model_get_contact (EABModel *model,
+ int row);
+EBook *eab_model_get_ebook (EABModel *model);
-void e_addressbook_model_stop (EAddressbookModel *model);
-gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
+void eab_model_stop (EABModel *model);
+gboolean eab_model_can_stop (EABModel *model);
-void e_addressbook_model_force_folder_bar_message (EAddressbookModel *model);
+void eab_model_force_folder_bar_message (EABModel *model);
-int e_addressbook_model_card_count (EAddressbookModel *model);
-ECard *e_addressbook_model_card_at (EAddressbookModel *model,
- int index);
-gboolean e_addressbook_model_editable (EAddressbookModel *model);
+int eab_model_contact_count (EABModel *model);
+const EContact *eab_model_contact_at (EABModel *model,
+ int index);
+gboolean eab_model_editable (EABModel *model);
-#endif /* _E_ADDRESSBOOK_MODEL_H_ */
+#endif /* _EAB_MODEL_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
index a4cb9364b5..cf1667fec5 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
@@ -5,26 +5,25 @@
#include <string.h>
#include <libgnome/gnome-i18n.h>
-#include "e-addressbook-marshal.h"
+#include "eab-marshal.h"
#include "e-addressbook-reflow-adapter.h"
#include "e-addressbook-model.h"
#include "e-addressbook-view.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
#include "e-minicard.h"
#include <gal/widgets/e-popup-menu.h>
#include <gal/widgets/e-gui-utils.h>
-#include "e-contact-save-as.h"
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
struct _EAddressbookReflowAdapterPrivate {
- EAddressbookModel *model;
+ EABModel *model;
gboolean loading;
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
+ int create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
int search_started_id, search_result_id;
};
@@ -53,15 +52,15 @@ unlink_model(EAddressbookReflowAdapter *adapter)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- if (priv->model && priv->create_card_id)
+ if (priv->model && priv->create_contact_id)
g_signal_handler_disconnect (priv->model,
- priv->create_card_id);
- if (priv->model && priv->remove_card_id)
+ priv->create_contact_id);
+ if (priv->model && priv->remove_contact_id)
g_signal_handler_disconnect (priv->model,
- priv->remove_card_id);
- if (priv->model && priv->modify_card_id)
+ priv->remove_contact_id);
+ if (priv->model && priv->modify_contact_id)
g_signal_handler_disconnect (priv->model,
- priv->modify_card_id);
+ priv->modify_contact_id);
if (priv->model && priv->model_changed_id)
g_signal_handler_disconnect (priv->model,
priv->model_changed_id);
@@ -72,9 +71,9 @@ unlink_model(EAddressbookReflowAdapter *adapter)
g_signal_handler_disconnect (priv->model,
priv->search_result_id);
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
priv->model_changed_id = 0;
priv->search_started_id = 0;
priv->search_result_id = 0;
@@ -104,20 +103,6 @@ addressbook_dispose(GObject *object)
EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
unlink_model (adapter);
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-addressbook_finalize(GObject *object)
-{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
-
- g_free (adapter->priv);
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
static void
@@ -132,37 +117,37 @@ addressbook_count (EReflowModel *erm)
EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return eab_model_contact_count (priv->model);
}
-/* This function returns the height of the minicard in question */
+/* This function returns the height of the minicontact in question */
static int
addressbook_height (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
{
EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- ECardSimpleField field;
+ EContactField field;
int count = 0;
char *string;
- ECardSimple *simple = e_card_simple_new (e_addressbook_model_card_at (priv->model, i));
+ EContact *contact = (EContact*)eab_model_contact_at (priv->model, i);
PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), "");
int height;
- string = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_FILE_AS);
+ string = e_contact_get(contact, E_CONTACT_FILE_AS);
height = text_height (layout, string ? string : "") + 10.0;
g_free(string);
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING && count < 5; field++) {
+ for(field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING && count < 5; field++) {
- if (field == E_CARD_SIMPLE_FIELD_FAMILY_NAME)
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
continue;
- string = e_card_simple_get(simple, field);
+ string = e_contact_get(contact, field);
if (string && *string) {
int this_height;
int field_text_height;
- this_height = text_height (layout, e_card_simple_get_name(simple, field));
+ this_height = text_height (layout, e_contact_pretty_name(field));
field_text_height = text_height (layout, string);
if (this_height < field_text_height)
@@ -177,7 +162,6 @@ addressbook_height (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
}
height += 2;
- g_object_unref (simple);
g_object_unref (layout);
return height;
@@ -188,30 +172,31 @@ addressbook_compare (EReflowModel *erm, int n1, int n2)
{
EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- ECard *card1, *card2;
+ EContact *contact1, *contact2;
if (priv->loading) {
return n1-n2;
}
else {
- card1 = e_addressbook_model_card_at (priv->model, n1);
- card2 = e_addressbook_model_card_at (priv->model, n2);
+ contact1 = (EContact*)eab_model_contact_at (priv->model, n1);
+ contact2 = (EContact*)eab_model_contact_at (priv->model, n2);
- if (card1 && card2) {
- char *file_as1, *file_as2;
- file_as1 = card1->file_as;
- file_as2 = card2->file_as;
+ if (contact1 && contact2) {
+ const char *file_as1, *file_as2;
+ file_as1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
+ file_as2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
if (file_as1 && file_as2)
return g_utf8_collate(file_as1, file_as2);
if (file_as1)
return -1;
if (file_as2)
return 1;
- return strcmp(e_card_get_id(card1), e_card_get_id(card2));
+ return strcmp(e_contact_get_const (contact1, E_CONTACT_UID),
+ e_contact_get_const (contact2, E_CONTACT_UID));
}
- if (card1)
+ if (contact1)
return -1;
- if (card2)
+ if (contact2)
return 1;
return 0;
}
@@ -238,8 +223,8 @@ addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
item = gnome_canvas_item_new(parent,
e_minicard_get_type(),
- "card", e_addressbook_model_card_at (priv->model, i),
- "editable", e_addressbook_model_editable (priv->model),
+ "contact", eab_model_contact_at (priv->model, i),
+ "editable", eab_model_editable (priv->model),
NULL);
#if 0
@@ -260,14 +245,14 @@ addressbook_reincarnate (EReflowModel *erm, int i, GnomeCanvasItem *item)
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
gnome_canvas_item_set(item,
- "card", e_addressbook_model_card_at (priv->model, i),
+ "contact", eab_model_contact_at (priv->model, i),
NULL);
}
static void
-create_card (EAddressbookModel *model,
- gint index, gint count,
- EAddressbookReflowAdapter *adapter)
+create_contact (EABModel *model,
+ gint index, gint count,
+ EAddressbookReflowAdapter *adapter)
{
e_reflow_model_items_inserted (E_REFLOW_MODEL (adapter),
index,
@@ -275,30 +260,30 @@ create_card (EAddressbookModel *model,
}
static void
-remove_card (EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+remove_contact (EABModel *model,
+ gint index,
+ EAddressbookReflowAdapter *adapter)
{
e_reflow_model_item_removed (E_REFLOW_MODEL (adapter), index);
}
static void
-modify_card (EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+modify_contact (EABModel *model,
+ gint index,
+ EAddressbookReflowAdapter *adapter)
{
e_reflow_model_item_changed (E_REFLOW_MODEL (adapter), index);
}
static void
-model_changed (EAddressbookModel *model,
+model_changed (EABModel *model,
EAddressbookReflowAdapter *adapter)
{
e_reflow_model_changed (E_REFLOW_MODEL (adapter));
}
static void
-search_started (EAddressbookModel *model,
+search_started (EABModel *model,
EAddressbookReflowAdapter *adapter)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
@@ -307,7 +292,7 @@ search_started (EAddressbookModel *model,
}
static void
-search_result (EAddressbookModel *model,
+search_result (EABModel *model,
EBookViewStatus status,
EAddressbookReflowAdapter *adapter)
{
@@ -387,7 +372,6 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class)
object_class->set_property = addressbook_set_property;
object_class->get_property = addressbook_get_property;
object_class->dispose = addressbook_dispose;
- object_class->finalize = addressbook_finalize;
g_object_class_install_property (object_class, PROP_BOOK,
g_param_spec_object ("book",
@@ -414,7 +398,7 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class)
g_param_spec_object ("model",
_("Model"),
/*_( */"XXX blurb" /*)*/,
- E_TYPE_ADDRESSBOOK_MODEL,
+ EAB_TYPE_MODEL,
G_PARAM_READABLE));
e_addressbook_reflow_adapter_signals [DRAG_BEGIN] =
@@ -423,7 +407,7 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, drag_begin),
NULL, NULL,
- e_addressbook_marshal_INT__POINTER,
+ eab_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
model_class->set_width = addressbook_set_width;
@@ -443,9 +427,9 @@ e_addressbook_reflow_adapter_init (GtkObject *object)
priv = adapter->priv = g_new0 (EAddressbookReflowAdapterPrivate, 1);
priv->loading = FALSE;
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
priv->model_changed_id = 0;
priv->search_started_id = 0;
priv->search_result_id = 0;
@@ -477,24 +461,24 @@ e_addressbook_reflow_adapter_get_type (void)
void
e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EAddressbookModel *model)
+ EABModel *model)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
priv->model = model;
g_object_ref (priv->model);
- priv->create_card_id = g_signal_connect(priv->model,
- "card_added",
- G_CALLBACK(create_card),
+ priv->create_contact_id = g_signal_connect(priv->model,
+ "contact_added",
+ G_CALLBACK(create_contact),
adapter);
- priv->remove_card_id = g_signal_connect(priv->model,
- "card_removed",
- G_CALLBACK(remove_card),
+ priv->remove_contact_id = g_signal_connect(priv->model,
+ "contact_removed",
+ G_CALLBACK(remove_contact),
adapter);
- priv->modify_card_id = g_signal_connect(priv->model,
- "card_changed",
- G_CALLBACK(modify_card),
+ priv->modify_contact_id = g_signal_connect(priv->model,
+ "contact_changed",
+ G_CALLBACK(modify_contact),
adapter);
priv->model_changed_id = g_signal_connect(priv->model,
"model_changed",
@@ -511,7 +495,7 @@ e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
}
EReflowModel *
-e_addressbook_reflow_adapter_new (EAddressbookModel *model)
+e_addressbook_reflow_adapter_new (EABModel *model)
{
EAddressbookReflowAdapter *et;
@@ -523,11 +507,11 @@ e_addressbook_reflow_adapter_new (EAddressbookModel *model)
}
-ECard *
-e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
- int index)
+EContact *
+e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
+ int index)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_get_card (priv->model, index);
+ return eab_model_get_contact (priv->model, index);
}
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
index 4bf131bc5c..9ba7d2cf2d 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
@@ -3,11 +3,8 @@
#define _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
#include <gal/widgets/e-reflow-model.h>
-#include <gal/widgets/e-selection-model.h>
#include "e-addressbook-model.h"
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card.h"
+#include "addressbook/backend/ebook/e-contact.h"
#define E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER (e_addressbook_reflow_adapter_get_type ())
#define E_ADDRESSBOOK_REFLOW_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapter))
@@ -38,10 +35,10 @@ struct _EAddressbookReflowAdapterClass {
GType e_addressbook_reflow_adapter_get_type (void);
void e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EAddressbookModel *model);
-EReflowModel *e_addressbook_reflow_adapter_new (EAddressbookModel *model);
+ EABModel *model);
+EReflowModel *e_addressbook_reflow_adapter_new (EABModel *model);
/* Returns object with ref count of 1. */
-ECard *e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
+EContact *e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
int index);
#endif /* _E_ADDRESSBOOK_REFLOW_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c
index 6a9e06da54..eb01b9b079 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c
@@ -3,87 +3,52 @@
#include <config.h>
#include "e-addressbook-model.h"
#include "e-addressbook-table-adapter.h"
-#include "e-card-merging.h"
-#include "e-addressbook-util.h"
-#include "ebook/e-destination.h"
+#include "eab-gui-util.h"
+#include "util/eab-destination.h"
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
#include <gnome.h>
struct _EAddressbookTableAdapterPrivate {
- EAddressbookModel *model;
+ EABModel *model;
- ECardSimple **simples;
- int count;
-
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
+ int create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
};
#define PARENT_TYPE e_table_model_get_type()
static ETableModelClass *parent_class;
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
+#define COLS (E_CONTACT_FIELD_LAST)
static void
unlink_model(EAddressbookTableAdapter *adapter)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
g_signal_handler_disconnect (priv->model,
- priv->create_card_id);
+ priv->create_contact_id);
g_signal_handler_disconnect (priv->model,
- priv->remove_card_id);
+ priv->remove_contact_id);
g_signal_handler_disconnect (priv->model,
- priv->modify_card_id);
+ priv->modify_contact_id);
g_signal_handler_disconnect (priv->model,
priv->model_changed_id);
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
priv->model_changed_id = 0;
- /* free up the existing mapping if there is one */
- if (priv->simples) {
- for (i = 0; i < priv->count; i ++)
- g_object_unref (priv->simples[i]);
- g_free (priv->simples);
- priv->simples = NULL;
- }
-
g_object_unref (priv->model);
priv->model = NULL;
}
static void
-build_simple_mapping(EAddressbookTableAdapter *adapter)
-{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
-
- /* free up the existing mapping if there is one */
- if (priv->simples) {
- for (i = 0; i < priv->count; i ++)
- g_object_unref (priv->simples[i]);
- g_free (priv->simples);
- }
-
- /* build up our mapping to ECardSimple*'s */
- priv->count = e_addressbook_model_card_count (priv->model);
- priv->simples = g_new (ECardSimple*, priv->count);
- for (i = 0; i < priv->count; i ++) {
- priv->simples[i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, i));
- g_object_ref (priv->simples[i]);
- }
-}
-
-static void
addressbook_dispose(GObject *object)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object);
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(object);
if (adapter->priv) {
unlink_model(adapter);
@@ -107,30 +72,30 @@ addressbook_col_count (ETableModel *etc)
static int
addressbook_row_count (ETableModel *etc)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return eab_model_contact_count (priv->model);
}
/* This function returns the value at a particular point in our ETableModel. */
static void *
addressbook_value_at (ETableModel *etc, int col, int row)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
const char *value;
- if ( col >= COLS || row >= e_addressbook_model_card_count (priv->model) )
+ if ( col >= COLS || row >= eab_model_contact_count (priv->model) )
return NULL;
- value = e_card_simple_get_const(priv->simples[row], col);
+ value = e_contact_get_const((EContact*)eab_model_contact_at (priv->model, row), col);
if (value && !strncmp (value, "<?xml", 5)) {
- EDestination *dest = e_destination_import (value);
+ EABDestination *dest = eab_destination_import (value);
if (dest) {
/* XXX blech, we leak this */
- value = g_strdup (e_destination_get_textrep (dest, TRUE));
+ value = g_strdup (eab_destination_get_textrep (dest, TRUE));
g_object_unref (dest);
}
}
@@ -140,22 +105,26 @@ addressbook_value_at (ETableModel *etc, int col, int row)
}
/* This function sets the value at a particular point in our ETableModel. */
+#if 0
static void
card_modified_cb (EBook* book, EBookStatus status,
gpointer user_data)
{
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
+ if (status != E_BOOK_ERROR_OK)
+ eab_error_dialog (_("Error modifying card"), status);
}
+#endif
+
static void
addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+#if 0
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- if (e_addressbook_model_editable (priv->model)) {
+ if (eab_model_editable (priv->model)) {
ECard *card;
- if ( col >= COLS|| row >= e_addressbook_model_card_count (priv->model) )
+ if ( col >= COLS|| row >= eab_model_card_count (priv->model) )
return;
e_table_model_pre_change(etc);
@@ -167,29 +136,31 @@ addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val)
"card", &card,
NULL);
- e_card_merging_book_commit_card(e_addressbook_model_get_ebook(priv->model),
+ e_card_merging_book_commit_card(eab_model_get_ebook(priv->model),
card, card_modified_cb, NULL);
g_object_unref (card);
/* XXX do we need this? shouldn't the commit_card generate a changed signal? */
e_table_model_cell_changed(etc, col, row);
}
+#endif
}
/* This function returns whether a particular cell is editable. */
static gboolean
addressbook_is_cell_editable (ETableModel *etc, int col, int row)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+#if 0
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
ECard *card;
- if (row >= 0 && row < e_addressbook_model_card_count (priv->model))
- card = e_addressbook_model_card_at (priv->model, row);
+ if (row >= 0 && row < eab_model_card_count (priv->model))
+ card = eab_model_card_at (priv->model, row);
else
card = NULL;
- if (!e_addressbook_model_editable(priv->model))
+ if (!eab_model_editable(priv->model))
return FALSE;
else if (card && e_card_evolution_list (card))
/* we only allow editing of the name and file as for
@@ -197,12 +168,16 @@ addressbook_is_cell_editable (ETableModel *etc, int col, int row)
return col == E_CARD_SIMPLE_FIELD_FULL_NAME || col == E_CARD_SIMPLE_FIELD_FILE_AS;
else
return col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING;
+#else
+ return FALSE;
+#endif
}
static void
addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etm);
+#if 0
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etm);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
ECard *card;
ECardSimple *simple;
@@ -216,9 +191,10 @@ addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
e_card_simple_set(simple, col, val);
}
e_card_simple_sync_card(simple);
- e_card_merging_book_add_card (e_addressbook_model_get_ebook (priv->model), card, NULL, NULL);
+ e_card_merging_book_add_card (eab_model_get_ebook (priv->model), card, NULL, NULL);
g_object_unref (simple);
g_object_unref (card);
+#endif
}
/* This function duplicates the value passed to it. */
@@ -254,7 +230,7 @@ addressbook_value_to_string (ETableModel *etc, int col, const void *value)
}
static void
-e_addressbook_table_adapter_class_init (GObjectClass *object_class)
+eab_table_adapter_class_init (GObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
@@ -276,82 +252,57 @@ e_addressbook_table_adapter_class_init (GObjectClass *object_class)
}
static void
-e_addressbook_table_adapter_init (GObject *object)
+eab_table_adapter_init (GObject *object)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object);
+ EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(object);
EAddressbookTableAdapterPrivate *priv;
priv = adapter->priv = g_new0 (EAddressbookTableAdapterPrivate, 1);
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
priv->model_changed_id = 0;
- priv->simples = NULL;
- priv->count = 0;
}
static void
-create_card (EAddressbookModel *model,
- gint index, gint count,
- EAddressbookTableAdapter *adapter)
+create_contact (EABModel *model,
+ gint index, gint count,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
-
- priv->count += count;
- priv->simples = g_renew(ECardSimple *, priv->simples, priv->count);
- memmove (priv->simples + index + count, priv->simples + index, (priv->count - index - count) * sizeof (ECardSimple *));
-
e_table_model_pre_change (E_TABLE_MODEL (adapter));
- for (i = 0; i < count; i ++) {
- priv->simples[index + i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index + i));
- }
e_table_model_rows_inserted (E_TABLE_MODEL (adapter), index, count);
}
static void
-remove_card (EAddressbookModel *model,
- gint index,
- EAddressbookTableAdapter *adapter)
+remove_contact (EABModel *model,
+ gint index,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
-
e_table_model_pre_change (E_TABLE_MODEL (adapter));
-
- g_object_unref (priv->simples[index]);
- memmove (priv->simples + index, priv->simples + index + 1, (priv->count - index - 1) * sizeof (ECardSimple *));
- priv->count --;
e_table_model_rows_deleted (E_TABLE_MODEL (adapter), index, 1);
}
static void
-modify_card (EAddressbookModel *model,
- gint index,
- EAddressbookTableAdapter *adapter)
+modify_contact (EABModel *model,
+ gint index,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
-
e_table_model_pre_change (E_TABLE_MODEL (adapter));
-
- g_object_unref (priv->simples[index]);
- priv->simples[index] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index));
- g_object_ref (priv->simples[index]);
e_table_model_row_changed (E_TABLE_MODEL (adapter), index);
}
static void
-model_changed (EAddressbookModel *model,
+model_changed (EABModel *model,
EAddressbookTableAdapter *adapter)
{
e_table_model_pre_change (E_TABLE_MODEL (adapter));
- build_simple_mapping (adapter);
e_table_model_changed (E_TABLE_MODEL (adapter));
}
GType
-e_addressbook_table_adapter_get_type (void)
+eab_table_adapter_get_type (void)
{
static GType type = 0;
@@ -360,12 +311,12 @@ e_addressbook_table_adapter_get_type (void)
sizeof (EAddressbookTableAdapterClass),
NULL, /* base_init */
NULL, /* base_finalize */
- (GClassInitFunc) e_addressbook_table_adapter_class_init,
+ (GClassInitFunc) eab_table_adapter_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EAddressbookTableAdapter),
0, /* n_preallocs */
- (GInstanceInitFunc) e_addressbook_table_adapter_init,
+ (GInstanceInitFunc) eab_table_adapter_init,
};
type = g_type_register_static (PARENT_TYPE, "EAddressbookTableAdapter", &info, 0);
@@ -375,42 +326,40 @@ e_addressbook_table_adapter_get_type (void)
}
void
-e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EAddressbookModel *model)
+eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
+ EABModel *model)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
priv->model = model;
g_object_ref (priv->model);
- priv->create_card_id = g_signal_connect(priv->model,
- "card_added",
- G_CALLBACK(create_card),
- adapter);
- priv->remove_card_id = g_signal_connect(priv->model,
- "card_removed",
- G_CALLBACK(remove_card),
- adapter);
- priv->modify_card_id = g_signal_connect(priv->model,
- "card_changed",
- G_CALLBACK(modify_card),
- adapter);
+ priv->create_contact_id = g_signal_connect(priv->model,
+ "contact_added",
+ G_CALLBACK(create_contact),
+ adapter);
+ priv->remove_contact_id = g_signal_connect(priv->model,
+ "contact_removed",
+ G_CALLBACK(remove_contact),
+ adapter);
+ priv->modify_contact_id = g_signal_connect(priv->model,
+ "contact_changed",
+ G_CALLBACK(modify_contact),
+ adapter);
priv->model_changed_id = g_signal_connect(priv->model,
"model_changed",
G_CALLBACK(model_changed),
adapter);
-
- build_simple_mapping (adapter);
}
ETableModel *
-e_addressbook_table_adapter_new (EAddressbookModel *model)
+eab_table_adapter_new (EABModel *model)
{
EAddressbookTableAdapter *et;
- et = g_object_new(E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, NULL);
+ et = g_object_new(E_TYPE_AB_TABLE_ADAPTER, NULL);
- e_addressbook_table_adapter_construct (et, model);
+ eab_table_adapter_construct (et, model);
return E_TABLE_MODEL(et);
}
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.h b/addressbook/gui/widgets/e-addressbook-table-adapter.h
index df66e1dce9..6f4bfd2960 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.h
@@ -1,24 +1,16 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_ADDRESSBOOK_TABLE_ADAPTER_H_
-#define _E_ADDRESSBOOK_TABLE_ADAPTER_H_
+#ifndef _EAB_TABLE_ADAPTER_H_
+#define _EAB_TABLE_ADAPTER_H_
#include <gal/e-table/e-table-model.h>
#include "addressbook/backend/ebook/e-book.h"
#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-#define E_TYPE_ADDRESSBOOK_TABLE_ADAPTER (e_addressbook_table_adapter_get_type ())
-#define E_ADDRESSBOOK_TABLE_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapter))
-#define E_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterClass))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
-
-/* Virtual Column list:
- 0 Email
- 1 Full Name
- 2 Street
- 3 Phone
-*/
+#define E_TYPE_AB_TABLE_ADAPTER (eab_table_adapter_get_type ())
+#define EAB_TABLE_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_AB_TABLE_ADAPTER, EAddressbookTableAdapter))
+#define EAB_TABLE_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_AB_TABLE_ADAPTER, EAddressbookTableAdapterClass))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_AB_TABLE_ADAPTER))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_AB_TABLE_ADAPTER))
typedef struct _EAddressbookTableAdapter EAddressbookTableAdapter;
typedef struct _EAddressbookTableAdapterPrivate EAddressbookTableAdapterPrivate;
@@ -36,9 +28,9 @@ struct _EAddressbookTableAdapterClass {
};
-GType e_addressbook_table_adapter_get_type (void);
-void e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EAddressbookModel *model);
-ETableModel *e_addressbook_table_adapter_new (EAddressbookModel *model);
+GType eab_table_adapter_get_type (void);
+void eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
+ EABModel *model);
+ETableModel *eab_table_adapter_new (EABModel *model);
-#endif /* _E_ADDRESSBOOK_TABLE_ADAPTER_H_ */
+#endif /* _EAB_TABLE_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-treeview-adapter.c b/addressbook/gui/widgets/e-addressbook-treeview-adapter.c
index ab1a559f0c..592f9d2b03 100644
--- a/addressbook/gui/widgets/e-addressbook-treeview-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-treeview-adapter.c
@@ -4,7 +4,7 @@
#include "e-addressbook-model.h"
#include "e-addressbook-treeview-adapter.h"
#include "e-card-merging.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
#include <gtk/gtktreednd.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
@@ -380,10 +380,10 @@ adapter_get_value (GtkTreeModel *tree_model,
v = e_card_simple_get_const(simple, column);
if (v && !strncmp (v, "<?xml", 5)) {
- EDestination *dest = e_destination_import (v);
+ EABDestination *dest = eab_destination_import (v);
if (dest) {
/* XXX blech, we leak this */
- v = g_strdup (e_destination_get_textrep (dest, TRUE));
+ v = g_strdup (eab_destination_get_textrep (dest, TRUE));
g_object_unref (dest);
}
}
diff --git a/addressbook/gui/widgets/e-addressbook-util.h b/addressbook/gui/widgets/e-addressbook-util.h
deleted file mode 100644
index e6ea3ab73b..0000000000
--- a/addressbook/gui/widgets/e-addressbook-util.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-addressbook-util.h
- * Copyright (C) 2001 Ximian, Inc.
- * Author: Chris Toshok <toshok@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __E_ADDRESSBOOK_UTIL_H__
-#define __E_ADDRESSBOOK_UTIL_H__
-
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-void e_addressbook_error_dialog (const gchar *msg,
- EBookStatus status);
-gint e_addressbook_prompt_save_dialog (GtkWindow *parent);
-EContactEditor *e_addressbook_show_contact_editor (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable);
-EContactListEditor *e_addressbook_show_contact_list_editor (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable);
-void e_addressbook_show_multiple_cards (EBook *book,
- GList *list,
- gboolean editable);
-void e_addressbook_transfer_cards (EBook *source,
- GList *cards, /* adopted */
- gboolean delete_from_source,
- GtkWindow *parent_window);
-
-typedef enum {
- E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT,
- E_ADDRESSBOOK_DISPOSITION_AS_TO,
-} EAddressbookDisposition;
-
-void e_addressbook_send_card (ECard *card,
- EAddressbookDisposition disposition);
-void e_addressbook_send_card_list (GList *cards,
- EAddressbookDisposition disposition);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_ADDRESSBOOK_UTIL_H__ */
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 08710c71b5..4c5976717f 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -43,26 +43,24 @@
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
-#include "gal-view-factory-minicard.h"
-#include "gal-view-minicard.h"
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
#include <gal/widgets/e-treeview-selection-model.h>
#include "gal-view-factory-treeview.h"
#include "gal-view-treeview.h"
#endif
+#include "gal-view-minicard.h"
+#include "gal-view-factory-minicard.h"
-#include "e-addressbook-marshal.h"
+#include "eab-marshal.h"
#include "e-addressbook-view.h"
#include "e-addressbook-model.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
#include "e-addressbook-table-adapter.h"
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
#include "e-addressbook-treeview-adapter.h"
#endif
-#include "e-addressbook-reflow-adapter.h"
-#include "e-minicard-view-widget.h"
-#include "e-contact-save-as.h"
-#include "e-card-merging.h"
+#include "eab-contact-merging.h"
#include "e-contact-editor.h"
#include <gdk/gdkkeysyms.h>
@@ -76,33 +74,33 @@
#define d(x)
-static void e_addressbook_view_init (EAddressbookView *card);
-static void e_addressbook_view_class_init (EAddressbookViewClass *klass);
+static void eab_view_init (EABView *card);
+static void eab_view_class_init (EABViewClass *klass);
-static void e_addressbook_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_addressbook_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static void e_addressbook_view_dispose (GObject *object);
-static void change_view_type (EAddressbookView *view, EAddressbookViewType view_type);
+static void eab_view_dispose (GObject *object);
+static void change_view_type (EABView *view, EABViewType view_type);
-static void status_message (GtkObject *object, const gchar *status, EAddressbookView *eav);
-static void search_result (GtkObject *object, EBookViewStatus status, EAddressbookView *eav);
-static void folder_bar_message (GtkObject *object, const gchar *status, EAddressbookView *eav);
-static void stop_state_changed (GtkObject *object, EAddressbookView *eav);
-static void writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav);
-static void backend_died (GtkObject *object, EAddressbookView *eav);
-static void command_state_change (EAddressbookView *eav);
-static void alphabet_state_change (EAddressbookView *eav, gunichar letter);
+static void status_message (GtkObject *object, const gchar *status, EABView *eav);
+static void search_result (GtkObject *object, EBookViewStatus status, EABView *eav);
+static void folder_bar_message (GtkObject *object, const gchar *status, EABView *eav);
+static void stop_state_changed (GtkObject *object, EABView *eav);
+static void writable_status (GtkObject *object, gboolean writable, EABView *eav);
+static void backend_died (GtkObject *object, EABView *eav);
+static void command_state_change (EABView *eav);
static void selection_clear_event (GtkWidget *invisible, GdkEventSelection *event,
- EAddressbookView *view);
+ EABView *view);
static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint time, EAddressbookView *view);
+ guint time, EABView *view);
static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint info, guint time_stamp, EAddressbookView *view);
+ guint info, guint time_stamp, EABView *view);
static void invisible_destroyed (gpointer data, GObject *where_object_was);
-static GtkTableClass *parent_class = NULL;
+#define PARENT_TYPE GTK_TYPE_EVENT_BOX
+static GtkEventBoxClass *parent_class = NULL;
/* The arguments we take */
enum {
@@ -117,7 +115,6 @@ enum {
SEARCH_RESULT,
FOLDER_BAR_MESSAGE,
COMMAND_STATE_CHANGE,
- ALPHABET_STATE_CHANGE,
LAST_SIGNAL
};
@@ -130,38 +127,38 @@ static GtkTargetEntry drag_types[] = {
};
static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
-static guint e_addressbook_view_signals [LAST_SIGNAL] = {0, };
+static guint eab_view_signals [LAST_SIGNAL] = {0, };
static GdkAtom clipboard_atom = GDK_NONE;
static GalViewCollection *collection = NULL;
GType
-e_addressbook_view_get_type (void)
+eab_view_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
- sizeof (EAddressbookViewClass),
+ sizeof (EABViewClass),
NULL, /* base_init */
NULL, /* base_finalize */
- (GClassInitFunc) e_addressbook_view_class_init,
+ (GClassInitFunc) eab_view_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (EAddressbookView),
+ sizeof (EABView),
0, /* n_preallocs */
- (GInstanceInitFunc) e_addressbook_view_init,
+ (GInstanceInitFunc) eab_view_init,
};
- type = g_type_register_static (GTK_TYPE_TABLE, "EAddressbookView", &info, 0);
+ type = g_type_register_static (PARENT_TYPE, "EABView", &info, 0);
}
return type;
}
static void
-e_addressbook_view_class_init (EAddressbookViewClass *klass)
+eab_view_class_init (EABViewClass *klass)
{
GObjectClass *object_class;
GtkWidgetClass *widget_class;
@@ -169,11 +166,11 @@ e_addressbook_view_class_init (EAddressbookViewClass *klass)
object_class = G_OBJECT_CLASS(klass);
widget_class = GTK_WIDGET_CLASS(klass);
- parent_class = gtk_type_class (gtk_table_get_type ());
+ parent_class = gtk_type_class (PARENT_TYPE);
- object_class->set_property = e_addressbook_view_set_property;
- object_class->get_property = e_addressbook_view_get_property;
- object_class->dispose = e_addressbook_view_dispose;
+ object_class->set_property = eab_view_set_property;
+ object_class->get_property = eab_view_get_property;
+ object_class->dispose = eab_view_dispose;
g_object_class_install_property (object_class, PROP_BOOK,
g_param_spec_object ("book",
@@ -193,137 +190,78 @@ e_addressbook_view_class_init (EAddressbookViewClass *klass)
g_param_spec_int ("type",
_("Type"),
/*_( */"XXX blurb" /*)*/,
- E_ADDRESSBOOK_VIEW_NONE,
-#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- E_ADDRESSBOOK_VIEW_TREEVIEW,
-#else
- E_ADDRESSBOOK_VIEW_MINICARD,
-#endif
- E_ADDRESSBOOK_VIEW_NONE,
+ EAB_VIEW_NONE,
+ EAB_VIEW_TABLE,
+ EAB_VIEW_NONE,
G_PARAM_READWRITE));
- e_addressbook_view_signals [STATUS_MESSAGE] =
+ eab_view_signals [STATUS_MESSAGE] =
g_signal_new ("status_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookViewClass, status_message),
+ G_STRUCT_OFFSET (EABViewClass, status_message),
NULL, NULL,
- e_addressbook_marshal_NONE__POINTER,
+ eab_marshal_NONE__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
- e_addressbook_view_signals [SEARCH_RESULT] =
+ eab_view_signals [SEARCH_RESULT] =
g_signal_new ("search_result",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookViewClass, search_result),
+ G_STRUCT_OFFSET (EABViewClass, search_result),
NULL, NULL,
- e_addressbook_marshal_NONE__INT,
+ eab_marshal_NONE__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE] =
+ eab_view_signals [FOLDER_BAR_MESSAGE] =
g_signal_new ("folder_bar_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookViewClass, folder_bar_message),
+ G_STRUCT_OFFSET (EABViewClass, folder_bar_message),
NULL, NULL,
- e_addressbook_marshal_NONE__POINTER,
+ eab_marshal_NONE__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
- e_addressbook_view_signals [COMMAND_STATE_CHANGE] =
+ eab_view_signals [COMMAND_STATE_CHANGE] =
g_signal_new ("command_state_change",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookViewClass, command_state_change),
+ G_STRUCT_OFFSET (EABViewClass, command_state_change),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
- e_addressbook_view_signals [ALPHABET_STATE_CHANGE] =
- g_signal_new ("alphabet_state_change",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EAddressbookViewClass, alphabet_state_change),
- NULL, NULL,
- e_addressbook_marshal_NONE__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
-
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
}
static void
-e_addressbook_view_init (EAddressbookView *eav)
+eab_view_init (EABView *eav)
{
- eav->view_type = E_ADDRESSBOOK_VIEW_NONE;
-
- eav->model = e_addressbook_model_new ();
-
- g_signal_connect (eav->model,
- "status_message",
- G_CALLBACK (status_message),
- eav);
-
- g_signal_connect (eav->model,
- "search_result",
- G_CALLBACK (search_result),
- eav);
-
- g_signal_connect (eav->model,
- "folder_bar_message",
- G_CALLBACK (folder_bar_message),
- eav);
-
- g_signal_connect (eav->model,
- "stop_state_changed",
- G_CALLBACK (stop_state_changed),
- eav);
-
- g_signal_connect (eav->model,
- "writable_status",
- G_CALLBACK (writable_status),
- eav);
-
- g_signal_connect (eav->model,
- "backend_died",
- G_CALLBACK (backend_died),
- eav);
-
- eav->editable = FALSE;
- eav->book = NULL;
- eav->query = g_strdup (SHOW_ALL_SEARCH);
+ eav->view_type = EAB_VIEW_NONE;
+ eav->model = NULL;
eav->object = NULL;
eav->widget = NULL;
+ eav->scrolled = NULL;
+ eav->contact_display = NULL;
eav->view_instance = NULL;
eav->view_menus = NULL;
+ eav->current_view = NULL;
eav->uic = NULL;
- eav->current_alphabet_widget = NULL;
- eav->invisible = gtk_invisible_new ();
+ eav->book = NULL;
+ eav->query = NULL;
- gtk_selection_add_target (eav->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- 0);
-
- g_signal_connect (eav->invisible, "selection_get",
- G_CALLBACK (selection_get),
- eav);
- g_signal_connect (eav->invisible, "selection_clear_event",
- G_CALLBACK (selection_clear_event),
- eav);
- g_signal_connect (eav->invisible, "selection_received",
- G_CALLBACK (selection_received),
- eav);
- g_object_weak_ref (G_OBJECT (eav->invisible), invisible_destroyed, eav);
+ eav->invisible = NULL;
+ eav->clipboard_contacts = NULL;
}
static void
-e_addressbook_view_dispose (GObject *object)
+eab_view_dispose (GObject *object)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ EABView *eav = EAB_VIEW(object);
if (eav->model) {
g_signal_handlers_disconnect_matched (eav->model,
@@ -356,10 +294,10 @@ e_addressbook_view_dispose (GObject *object)
eav->view_menus = NULL;
}
- if (eav->clipboard_cards) {
- g_list_foreach (eav->clipboard_cards, (GFunc)g_object_unref, NULL);
- g_list_free (eav->clipboard_cards);
- eav->clipboard_cards = NULL;
+ if (eav->clipboard_contacts) {
+ g_list_foreach (eav->clipboard_contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (eav->clipboard_contacts);
+ eav->clipboard_contacts = NULL;
}
if (eav->invisible) {
@@ -372,14 +310,77 @@ e_addressbook_view_dispose (GObject *object)
}
GtkWidget*
-e_addressbook_view_new (void)
-{
- GtkWidget *widget = GTK_WIDGET (g_object_new (E_TYPE_ADDRESSBOOK_VIEW, NULL));
+eab_view_new (void)
+{
+ GtkWidget *widget = GTK_WIDGET (g_object_new (E_TYPE_AB_VIEW, NULL));
+ EABView *eav = EAB_VIEW (widget);
+
+ /* create our model */
+ eav->model = eab_model_new ();
+
+ g_signal_connect (eav->model, "status_message",
+ G_CALLBACK (status_message), eav);
+ g_signal_connect (eav->model, "search_result",
+ G_CALLBACK (search_result), eav);
+ g_signal_connect (eav->model, "folder_bar_message",
+ G_CALLBACK (folder_bar_message), eav);
+ g_signal_connect (eav->model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), eav);
+ g_signal_connect (eav->model, "writable_status",
+ G_CALLBACK (writable_status), eav);
+ g_signal_connect (eav->model, "backend_died",
+ G_CALLBACK (backend_died), eav);
+
+ eav->editable = FALSE;
+ eav->query = g_strdup (SHOW_ALL_SEARCH);
+
+ /* create the paned window and contact display */
+ eav->paned = gtk_vpaned_new ();
+ gtk_container_add (GTK_CONTAINER (eav), eav->paned);
+
+ eav->widget = gtk_label_new ("empty label here");
+ gtk_container_add (GTK_CONTAINER (eav->paned), eav->widget);
+ gtk_widget_show (eav->widget);
+
+ eav->scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (eav->scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (eav->scrolled), GTK_SHADOW_IN);
+ eav->contact_display = eab_contact_display_new ();
+
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (eav->scrolled), eav->contact_display);
+ gtk_widget_show (eav->contact_display);
+
+ gtk_container_add (GTK_CONTAINER (eav->paned), eav->scrolled);
+ gtk_widget_show (eav->scrolled);
+ gtk_widget_show (eav->paned);
+
+ /* XXX hack */
+ gtk_paned_set_position (GTK_PANED (eav->paned), 144);
+
+ /* gtk selection crap */
+ eav->invisible = gtk_invisible_new ();
+
+ gtk_selection_add_target (eav->invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ 0);
+
+ g_signal_connect (eav->invisible, "selection_get",
+ G_CALLBACK (selection_get),
+ eav);
+ g_signal_connect (eav->invisible, "selection_clear_event",
+ G_CALLBACK (selection_clear_event),
+ eav);
+ g_signal_connect (eav->invisible, "selection_received",
+ G_CALLBACK (selection_received),
+ eav);
+ g_object_weak_ref (G_OBJECT (eav->invisible), invisible_destroyed, eav);
+
return widget;
}
static void
-writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav)
+writable_status (GtkObject *object, gboolean writable, EABView *eav)
{
eav->editable = writable;
command_state_change (eav);
@@ -412,7 +413,7 @@ init_collection (void)
gal_view_collection_add_factory (collection, factory);
g_object_unref (factory);
- factory = gal_view_factory_minicard_new ();
+ factory = gal_view_factory_minicard_new();
gal_view_collection_add_factory (collection, factory);
g_object_unref (factory);
@@ -431,17 +432,18 @@ display_view(GalViewInstance *instance,
GalView *view,
gpointer data)
{
- EAddressbookView *address_view = data;
+ EABView *address_view = data;
if (GAL_IS_VIEW_ETABLE(view)) {
- change_view_type (address_view, E_ADDRESSBOOK_VIEW_TABLE);
+ change_view_type (address_view, EAB_VIEW_TABLE);
gal_view_etable_attach_table (GAL_VIEW_ETABLE(view), e_table_scrolled_get_table(E_TABLE_SCROLLED(address_view->widget)));
- } else if (GAL_IS_VIEW_MINICARD(view)) {
- change_view_type (address_view, E_ADDRESSBOOK_VIEW_MINICARD);
- gal_view_minicard_attach (GAL_VIEW_MINICARD(view), E_MINICARD_VIEW_WIDGET (address_view->object));
+ }
+ else if (GAL_IS_VIEW_MINICARD(view)) {
+ change_view_type (address_view, EAB_VIEW_MINICARD);
+ gal_view_minicard_attach (GAL_VIEW_MINICARD (view), E_MINICARD_VIEW_WIDGET (address_view->object));
}
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
else if (GAL_IS_VIEW_TREEVIEW (view)) {
- change_view_type (address_view, E_ADDRESSBOOK_VIEW_TREEVIEW);
+ change_view_type (address_view, EAB_VIEW_TREEVIEW);
gal_view_treeview_attach (GAL_VIEW_TREEVIEW(view), GTK_TREE_VIEW (address_view->object));
}
#endif
@@ -449,7 +451,7 @@ display_view(GalViewInstance *instance,
}
static void
-setup_menus (EAddressbookView *view)
+setup_menus (EABView *view)
{
if (view->book && view->view_instance == NULL) {
init_collection ();
@@ -468,9 +470,9 @@ setup_menus (EAddressbookView *view)
}
static void
-e_addressbook_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ EABView *eav = EAB_VIEW(object);
switch (prop_id){
case PROP_BOOK:
@@ -509,12 +511,6 @@ e_addressbook_view_set_property (GObject *object, guint prop_id, const GValue *v
g_object_set(eav->model,
"query", eav->query,
NULL);
- if (eav->current_alphabet_widget != NULL) {
- GtkWidget *current = eav->current_alphabet_widget;
-
- eav->current_alphabet_widget = NULL;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current), FALSE);
- }
break;
case PROP_TYPE:
change_view_type(eav, g_value_get_int (value));
@@ -526,9 +522,9 @@ e_addressbook_view_set_property (GObject *object, guint prop_id, const GValue *v
}
static void
-e_addressbook_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ EABView *eav = EAB_VIEW(object);
switch (prop_id) {
case PROP_BOOK:
@@ -550,44 +546,43 @@ e_addressbook_view_get_property (GObject *object, guint prop_id, GValue *value,
}
static ESelectionModel*
-get_selection_model (EAddressbookView *view)
+get_selection_model (EABView *view)
{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD)
- return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE)
+ if (view->view_type == EAB_VIEW_TABLE)
return e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(view->widget)));
+ else if (view->view_type == EAB_VIEW_MINICARD)
+ return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TREEVIEW) {
+ else if (view->view_type == EAB_VIEW_TREEVIEW)
return e_treeview_get_selection_model (GTK_TREE_VIEW (view->object));
- }
#endif
g_return_val_if_reached (NULL);
}
/* Popup menu stuff */
typedef struct {
- EAddressbookView *view;
+ EABView *view;
EPopupMenu *submenu;
gpointer closure;
-} CardAndBook;
+} ContactAndBook;
static ESelectionModel*
-card_and_book_get_selection_model (CardAndBook *card_and_book)
+contact_and_book_get_selection_model (ContactAndBook *contact_and_book)
{
- return get_selection_model (card_and_book->view);
+ return get_selection_model (contact_and_book->view);
}
static void
-card_and_book_free (CardAndBook *card_and_book)
+contact_and_book_free (ContactAndBook *contact_and_book)
{
- EAddressbookView *view = card_and_book->view;
+ EABView *view = contact_and_book->view;
ESelectionModel *selection;
- if (card_and_book->submenu)
+ if (contact_and_book->submenu)
gal_view_instance_free_popup_menu (view->view_instance,
- card_and_book->submenu);
+ contact_and_book->submenu);
- selection = card_and_book_get_selection_model (card_and_book);
+ selection = contact_and_book_get_selection_model (contact_and_book);
if (selection)
e_selection_model_right_click_up(selection);
@@ -595,33 +590,33 @@ card_and_book_free (CardAndBook *card_and_book)
}
static void
-get_card_list_1(gint model_row,
- gpointer closure)
+get_contact_list_1(gint model_row,
+ gpointer closure)
{
- CardAndBook *card_and_book;
+ ContactAndBook *contact_and_book;
GList **list;
- EAddressbookView *view;
- ECard *card;
+ EABView *view;
+ EContact *contact;
- card_and_book = closure;
- list = card_and_book->closure;
- view = card_and_book->view;
+ contact_and_book = closure;
+ list = contact_and_book->closure;
+ view = contact_and_book->view;
- card = e_addressbook_model_get_card(view->model, model_row);
- *list = g_list_prepend(*list, card);
+ contact = eab_model_get_contact(view->model, model_row);
+ *list = g_list_prepend(*list, contact);
}
static GList *
-get_card_list (CardAndBook *card_and_book)
+get_contact_list (ContactAndBook *contact_and_book)
{
GList *list = NULL;
ESelectionModel *selection;
- selection = card_and_book_get_selection_model (card_and_book);
+ selection = contact_and_book_get_selection_model (contact_and_book);
if (selection) {
- card_and_book->closure = &list;
- e_selection_model_foreach (selection, get_card_list_1, card_and_book);
+ contact_and_book->closure = &list;
+ e_selection_model_foreach (selection, get_contact_list_1, contact_and_book);
}
return list;
@@ -631,135 +626,134 @@ static void
has_email_address_1(gint model_row,
gpointer closure)
{
- CardAndBook *card_and_book;
+ ContactAndBook *contact_and_book;
gboolean *has_email;
- EAddressbookView *view;
- const ECard *card;
- EList *email;
+ EABView *view;
+ const EContact *contact;
+ GList *email;
- card_and_book = closure;
- has_email = card_and_book->closure;
- view = card_and_book->view;
+ contact_and_book = closure;
+ has_email = contact_and_book->closure;
+ view = contact_and_book->view;
if (*has_email)
return;
- card = e_addressbook_model_peek_card(view->model, model_row);
+ contact = eab_model_contact_at(view->model, model_row);
- g_object_get (G_OBJECT (card),
- "email", &email,
- NULL);
+ email = e_contact_get (E_CONTACT (contact), E_CONTACT_EMAIL);
- if (e_list_length (email) > 0)
+ if (g_list_length (email) > 0)
*has_email = TRUE;
- g_object_unref (email);
+ g_list_foreach (email, (GFunc)g_free, NULL);
+ g_list_free (email);
}
static gboolean
-get_has_email_address (CardAndBook *card_and_book)
+get_has_email_address (ContactAndBook *contact_and_book)
{
ESelectionModel *selection;
gboolean has_email = FALSE;
- selection = card_and_book_get_selection_model (card_and_book);
+ selection = contact_and_book_get_selection_model (contact_and_book);
if (selection) {
- card_and_book->closure = &has_email;
- e_selection_model_foreach (selection, has_email_address_1, card_and_book);
+ contact_and_book->closure = &has_email;
+ e_selection_model_foreach (selection, has_email_address_1, contact_and_book);
}
return has_email;
}
static void
-save_as (GtkWidget *widget, CardAndBook *card_and_book)
+save_as (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- e_contact_list_save_as(_("Save as VCard"), cards, NULL);
- e_free_object_list(cards);
+ GList *contacts = get_contact_list (contact_and_book);
+ if (contacts) {
+ eab_contact_list_save(_("Save as VCard"), contacts, NULL);
+ e_free_object_list(contacts);
}
}
static void
-send_as (GtkWidget *widget, CardAndBook *card_and_book)
+send_as (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- e_addressbook_send_card_list(cards, E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(cards);
+ GList *contacts = get_contact_list (contact_and_book);
+ if (contacts) {
+ eab_send_contact_list(contacts, EAB_DISPOSITION_AS_ATTACHMENT);
+ e_free_object_list(contacts);
}
}
static void
-send_to (GtkWidget *widget, CardAndBook *card_and_book)
+send_to (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- GList *cards = get_card_list (card_and_book);
+ GList *contacts = get_contact_list (contact_and_book);
- if (cards) {
- e_addressbook_send_card_list(cards, E_ADDRESSBOOK_DISPOSITION_AS_TO);
- e_free_object_list(cards);
+ if (contacts) {
+ eab_send_contact_list(contacts, EAB_DISPOSITION_AS_TO);
+ e_free_object_list(contacts);
}
}
static void
-print (GtkWidget *widget, CardAndBook *card_and_book)
+print (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- if (cards->next)
- gtk_widget_show(e_contact_print_card_list_dialog_new(cards));
+ GList *contacts = get_contact_list (contact_and_book);
+ if (contacts) {
+ if (contacts->next)
+ gtk_widget_show(e_contact_print_contact_list_dialog_new(contacts));
else
- gtk_widget_show(e_contact_print_card_dialog_new(cards->data));
- e_free_object_list(cards);
+ gtk_widget_show(e_contact_print_contact_dialog_new(contacts->data));
+ e_free_object_list(contacts);
}
}
#if 0 /* Envelope printing is disabled for Evolution 1.0. */
static void
-print_envelope (GtkWidget *widget, CardAndBook *card_and_book)
+print_envelope (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- GList *cards = get_card_list (card_and_book);
+ GList *cards = get_card_list (contact_and_book);
if (cards) {
- gtk_widget_show(e_contact_list_print_envelope_dialog_new(card_and_book->card));
+ gtk_widget_show(e_contact_list_print_envelope_dialog_new(contact_and_book->card));
e_free_object_list(cards);
}
}
#endif
static void
-copy (GtkWidget *widget, CardAndBook *card_and_book)
+copy (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- e_addressbook_view_copy (card_and_book->view);
+ eab_view_copy (contact_and_book->view);
}
static void
-paste (GtkWidget *widget, CardAndBook *card_and_book)
+paste (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- e_addressbook_view_paste (card_and_book->view);
+ eab_view_paste (contact_and_book->view);
}
static void
-cut (GtkWidget *widget, CardAndBook *card_and_book)
+cut (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- e_addressbook_view_cut (card_and_book->view);
+ eab_view_cut (contact_and_book->view);
}
static void
-delete (GtkWidget *widget, CardAndBook *card_and_book)
+delete (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- if (e_contact_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(card_and_book->view->widget)))) {
+ if (e_contact_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(contact_and_book->view->widget)))) {
EBook *book;
- GList *list = get_card_list(card_and_book);
+ GList *list = get_contact_list(contact_and_book);
GList *iterator;
gboolean bulk_remove = FALSE;
- bulk_remove = e_book_check_static_capability (card_and_book->view->model->book,
+ bulk_remove = e_book_check_static_capability (contact_and_book->view->model->book,
"bulk-remove");
- g_object_get(card_and_book->view->model,
+ g_object_get(contact_and_book->view->model,
"book", &book,
NULL);
@@ -767,26 +761,28 @@ delete (GtkWidget *widget, CardAndBook *card_and_book)
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));
+ EContact *contact = iterator->data;
+ ids = g_list_prepend (ids, (char*)e_contact_get_const (contact, E_CONTACT_UID));
}
/* Remove the cards all at once. */
- e_book_remove_cards (book,
- ids,
- NULL,
- NULL);
+ /* XXX no callback specified... ugh */
+ e_book_async_remove_contacts (book,
+ ids,
+ NULL,
+ NULL);
g_list_free (ids);
}
else {
for (iterator = list; iterator; iterator = iterator->next) {
- ECard *card = iterator->data;
+ EContact *contact = iterator->data;
/* Remove the card. */
- e_book_remove_card (book,
- card,
- NULL,
- NULL);
+ /* XXX no callback specified... ugh */
+ e_book_async_remove_contact (book,
+ e_contact_get_const (contact, E_CONTACT_UID),
+ NULL,
+ NULL);
}
}
e_free_object_list(list);
@@ -795,56 +791,55 @@ delete (GtkWidget *widget, CardAndBook *card_and_book)
}
static void
-copy_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
+copy_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- e_addressbook_view_copy_to_folder (card_and_book->view);
+ eab_view_copy_to_folder (contact_and_book->view);
}
static void
-move_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
+move_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book)
{
- e_addressbook_view_move_to_folder (card_and_book->view);
+ eab_view_move_to_folder (contact_and_book->view);
}
static void
-free_popup_info (GtkWidget *w, CardAndBook *card_and_book)
+free_popup_info (GtkWidget *w, ContactAndBook *contact_and_book)
{
- card_and_book_free (card_and_book);
+ contact_and_book_free (contact_and_book);
}
static void
-new_card (GtkWidget *widget, CardAndBook *card_and_book)
+new_card (GtkWidget *widget, ContactAndBook *contact_and_book)
{
EBook *book;
- ECard *card;
+ EContact *contact = e_contact_new();
- g_object_get(card_and_book->view->model,
+ g_object_get(contact_and_book->view->model,
"book", &book,
NULL);
- e_addressbook_show_contact_editor (book, card = e_card_new(""), TRUE, TRUE);
- g_object_unref(book);
- g_object_unref(card);
+ eab_show_contact_editor (book, contact, TRUE, TRUE);
+ g_object_unref (book);
+ g_object_unref (contact);
}
static void
-new_list (GtkWidget *widget, CardAndBook *card_and_book)
+new_list (GtkWidget *widget, ContactAndBook *contact_and_book)
{
EBook *book;
- ECard *card;
+ EContact *contact = e_contact_new ();
- g_object_get(card_and_book->view->model,
+ g_object_get(contact_and_book->view->model,
"book", &book,
NULL);
-
- e_addressbook_show_contact_list_editor (book, card = e_card_new(""), TRUE, TRUE);
+ eab_show_contact_list_editor (book, contact, TRUE, TRUE);
g_object_unref(book);
- g_object_unref(card);
+ g_object_unref(contact);
}
#if 0
static void
-sources (GtkWidget *widget, CardAndBook *card_and_book)
+sources (GtkWidget *widget, ContactAndBook *contact_and_book)
{
BonoboControl *control;
GNOME_Evolution_ShellView shell_view;
@@ -874,9 +869,9 @@ sources (GtkWidget *widget, CardAndBook *card_and_book)
#define POPUP_NOEMAIL_MASK 0x4
static void
-do_popup_menu(EAddressbookView *view, GdkEvent *event)
+do_popup_menu(EABView *view, GdkEvent *event)
{
- CardAndBook *card_and_book;
+ ContactAndBook *contact_and_book;
GtkMenu *popup;
EPopupMenu *submenu = NULL;
ESelectionModel *selection_model;
@@ -921,308 +916,62 @@ do_popup_menu(EAddressbookView *view, GdkEvent *event)
E_POPUP_TERMINATOR
};
- card_and_book = g_new(CardAndBook, 1);
- card_and_book->view = view;
- card_and_book->submenu = submenu;
+ contact_and_book = g_new(ContactAndBook, 1);
+ contact_and_book->view = view;
+ contact_and_book->submenu = submenu;
- g_object_ref (card_and_book->view);
+ g_object_ref (contact_and_book->view);
- selection_model = card_and_book_get_selection_model (card_and_book);
+ selection_model = contact_and_book_get_selection_model (contact_and_book);
if (selection_model)
selection = e_selection_model_selected_count (selection_model) > 0;
popup = e_popup_menu_create (menu,
0,
- (e_addressbook_model_editable (view->model) ? 0 : POPUP_READONLY_MASK) +
+ (eab_model_editable (view->model) ? 0 : POPUP_READONLY_MASK) +
(selection ? 0 : POPUP_NOSELECTION_MASK) +
- (get_has_email_address (card_and_book) ? 0 : POPUP_NOEMAIL_MASK),
- card_and_book);
+ (get_has_email_address (contact_and_book) ? 0 : POPUP_NOEMAIL_MASK),
+ contact_and_book);
g_signal_connect (popup, "selection-done",
- G_CALLBACK (free_popup_info), card_and_book);
+ G_CALLBACK (free_popup_info), contact_and_book);
e_popup_menu (popup, event);
}
-
-/* Minicard view stuff */
-
-/* Translators: put here a list of labels you want to see on buttons in
- addressbook. You may use any character to separate labels but it must
- also be placed at the begining ot the string */
-const char *button_labels = N_(",123,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z");
-/* Translators: put here a list of characters that correspond to buttons
- in addressbook. You may use any character to separate labels but it
- must also be placed at the begining ot the string.
- Use lower case letters if possible. */
-const char *button_letters = N_(",0,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z");
-
-typedef struct {
- EAddressbookView *view;
- GtkWidget *button;
- GtkWidget *vbox;
- gchar *letters;
-} LetterClosure;
-
-static char **
-e_utf8_split (const char *utf8_str, gunichar delim)
-{
- GSList *str_list = NULL, *sl;
- int n = 0;
- const char *str, *s;
- char **str_array;
-
- g_return_val_if_fail (utf8_str != NULL, NULL);
-
- str = utf8_str;
- while (*str != '\0') {
- int len;
- char *new_str;
-
- for (s = str; *s != '\0' && g_utf8_get_char (s) != delim; s = g_utf8_next_char (s))
- ;
- len = s - str;
- new_str = g_new (char, len + 1);
- if (len > 0) {
- memcpy (new_str, str, len);
- }
- new_str[len] = '\0';
- str_list = g_slist_prepend (str_list, new_str);
- n++;
- if (*s != '\0') {
- str = g_utf8_next_char (s);
- } else {
- str = s;
- }
- }
-
- str_array = g_new (char *, n + 1);
- str_array[n--] = NULL;
- for (sl = str_list; sl != NULL; sl = sl->next) {
- str_array[n--] = sl->data;
- }
- g_slist_free (str_list);
-
- return str_array;
-}
-
static void
-jump_to_letters (EAddressbookView *view, gchar* l)
-{
- char *query;
- char *s;
- char buf[6 + 1];
-
- if (g_unichar_isdigit (g_utf8_get_char(l))) {
- const char *letters = _(button_letters);
- char **letter_v;
- GString *gstr;
- char **p;
-
- letter_v = e_utf8_split (g_utf8_next_char (letters),
- g_utf8_get_char (letters));
- g_assert (letter_v != NULL && letter_v[0] != NULL);
- gstr = g_string_new ("(not (or ");
- for (p = letter_v + 1; *p != NULL; p++) {
- for (s = *p; *s != '\0'; s = g_utf8_next_char (s)) {
- buf [g_unichar_to_utf8 (g_utf8_get_char(s), buf)] = '\0';
- g_string_append_printf (gstr, "(beginswith \"file_as\" \"%s\")", buf);
- }
- }
- g_string_append (gstr, "))");
- query = gstr->str;
- g_strfreev (letter_v);
- g_string_free (gstr, FALSE);
- } else {
- GString *gstr;
-
- gstr = g_string_new ("(or ");
-
- for (s = l; *s != '\0'; s = g_utf8_next_char (s)) {
- buf [g_unichar_to_utf8 (g_utf8_get_char(s), buf)] = '\0';
- g_string_append_printf (gstr, "(beginswith \"file_as\" \"%s\")", buf);
- }
-
- g_string_append (gstr, ")");
- query = gstr->str;
- g_string_free (gstr, FALSE);
- }
- g_object_set (view,
- "query", query,
- NULL);
- g_free (query);
-}
-
-static void
-button_toggled(GtkWidget *button, LetterClosure *closure)
+render_contact (int row, EABView *view)
{
- EAddressbookView *view = closure->view;
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
- GtkWidget *current = view->current_alphabet_widget;
+ EContact *contact = eab_model_get_contact (view->model, row);
- view->current_alphabet_widget = NULL;
- if (current && current != button)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current), FALSE);
- jump_to_letters (view, closure->letters);
- view->current_alphabet_widget = button;
- alphabet_state_change (view, g_utf8_get_char(closure->letters));
- } else {
- if (view->current_alphabet_widget != NULL &&
- view->current_alphabet_widget == button) {
- view->current_alphabet_widget = NULL;
- g_object_set (view,
- "query", NULL,
- NULL);
- alphabet_state_change (view, 0);
- }
- }
+ eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), contact,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL);
}
static void
-free_closure(gpointer data, GObject *where_object_was)
+selection_changed (GObject *o, EABView *view)
{
- GtkWidget *button = GTK_WIDGET (where_object_was);
- LetterClosure *closure = data;
- if (button != NULL &&
- button == closure->view->current_alphabet_widget) {
- closure->view->current_alphabet_widget = NULL;
- }
- g_free (closure->letters);
- g_free (closure);
-}
-
-static GtkWidget *
-create_alphabet (EAddressbookView *view)
-{
- GtkWidget *widget, *viewport, *vbox;
- const char *labels, *letters;
- char **label_v, **letter_v;
- char **pl, **pc;
- gunichar sep;
-
- widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-
- viewport = gtk_viewport_new (NULL, NULL);
- gtk_container_add (GTK_CONTAINER (widget), viewport);
- gtk_container_set_border_width (GTK_CONTAINER (viewport), 4);
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
-
- vbox = gtk_vbox_new (FALSE, 4);
- gtk_container_add (GTK_CONTAINER (viewport), vbox);
-
- labels = _(button_labels);
- sep = g_utf8_get_char (labels);
- label_v = e_utf8_split (g_utf8_next_char (labels), sep);
- letters = _(button_letters);
- sep = g_utf8_get_char (letters);
- letter_v = e_utf8_split (g_utf8_next_char (letters), sep);
- g_assert (label_v != NULL && letter_v != NULL);
- for (pl = label_v, pc = letter_v; *pl != NULL && *pc != NULL; pl++, pc++) {
- GtkWidget *button;
- LetterClosure *closure;
- char *label;
-
- label = *pl;
- button = gtk_toggle_button_new_with_label (label);
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- closure = g_new (LetterClosure, 1);
- closure->view = view;
- closure->letters = g_strdup (*pc);
- closure->button = button;
- closure->vbox = vbox;
- g_signal_connect(button, "toggled",
- G_CALLBACK (button_toggled), closure);
- g_object_weak_ref (G_OBJECT (button), free_closure, closure);
-
- }
- g_strfreev (label_v);
- g_strfreev (letter_v);
-
- gtk_widget_show_all (widget);
-
- return widget;
-}
+ ESelectionModel *selection_model;
-static void
-selection_changed (GObject *o, EAddressbookView *view)
-{
command_state_change (view);
-}
-
-static void
-minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EAddressbookView *view)
-{
- do_popup_menu(view, event);
-}
-
-static void
-create_minicard_view (EAddressbookView *view)
-{
- GtkWidget *scrolled_window;
- GtkWidget *alphabet;
- GtkWidget *minicard_view;
- GtkWidget *minicard_hbox;
- EAddressbookReflowAdapter *adapter;
-
- gtk_widget_push_colormap (gdk_rgb_get_cmap ());
-
- minicard_hbox = gtk_hbox_new(FALSE, 0);
-
- adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model));
- minicard_view = e_minicard_view_widget_new(adapter);
-
- /* A hack */
- g_object_set_data (G_OBJECT (adapter), "view", view);
-
- g_signal_connect(minicard_view, "selection_change",
- G_CALLBACK(selection_changed), view);
-
- g_signal_connect(minicard_view, "right_click",
- G_CALLBACK(minicard_right_click), view);
-
-
- view->object = G_OBJECT(minicard_view);
- view->widget = minicard_hbox;
-
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- gtk_container_add (GTK_CONTAINER (scrolled_window), minicard_view);
-
- gtk_box_pack_start(GTK_BOX(minicard_hbox), scrolled_window, TRUE, TRUE, 0);
-
- alphabet = create_alphabet(view);
- if (alphabet)
- gtk_box_pack_start(GTK_BOX(minicard_hbox), alphabet, FALSE, FALSE, 0);
-
- gtk_table_attach(GTK_TABLE(view), minicard_hbox,
- 0, 1,
- 0, 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
-
- gtk_widget_show_all( GTK_WIDGET(minicard_hbox) );
-
- gtk_widget_pop_colormap ();
-
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+ selection_model = get_selection_model (view);
- g_object_unref (adapter);
+ if (e_selection_model_selected_count (selection_model) == 1)
+ e_selection_model_foreach (selection_model,
+ (EForeachFunc)render_contact, view);
+ else
+ eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+
}
static void
-table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
+table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view)
{
if (E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) {
- EAddressbookModel *model = view->model;
- ECard *card = e_addressbook_model_get_card(model, row);
+ EABModel *model = view->model;
+ EContact *contact = eab_model_get_contact (model, row);
EBook *book;
g_object_get(model,
@@ -1231,25 +980,25 @@ table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, E
g_assert (E_IS_BOOK (book));
- if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, view->editable);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ eab_show_contact_list_editor (book, contact, FALSE, view->editable);
else
- e_addressbook_show_contact_editor (book, card, FALSE, view->editable);
+ eab_show_contact_editor (book, contact, FALSE, view->editable);
g_object_unref (book);
- g_object_unref (card);
+ g_object_unref (contact);
}
}
static gint
-table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
+table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view)
{
do_popup_menu(view, event);
return TRUE;
}
static gint
-table_white_space_event(ETableScrolled *table, GdkEvent *event, EAddressbookView *view)
+table_white_space_event(ETableScrolled *table, GdkEvent *event, EABView *view)
{
if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) {
do_popup_menu(view, event);
@@ -1269,7 +1018,7 @@ table_drag_data_get (ETable *table,
guint time,
gpointer user_data)
{
- EAddressbookView *view = user_data;
+ EABView *view = user_data;
if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object))
return;
@@ -1278,7 +1027,7 @@ table_drag_data_get (ETable *table,
case DND_TARGET_TYPE_VCARD: {
char *value;
- value = e_card_get_vcard(view->model->data[row]);
+ value = e_vcard_to_string (E_VCARD (view->model->data[row]), EVC_FORMAT_VCARD_30);
gtk_selection_data_set (selection_data,
selection_data->target,
@@ -1290,68 +1039,62 @@ table_drag_data_get (ETable *table,
}
static void
-emit_status_message (EAddressbookView *eav, const gchar *status)
+emit_status_message (EABView *eav, const gchar *status)
{
g_signal_emit (eav,
- e_addressbook_view_signals [STATUS_MESSAGE], 0,
+ eab_view_signals [STATUS_MESSAGE], 0,
status);
}
static void
-emit_search_result (EAddressbookView *eav, EBookViewStatus status)
+emit_search_result (EABView *eav, EBookViewStatus status)
{
g_signal_emit (eav,
- e_addressbook_view_signals [SEARCH_RESULT], 0,
+ eab_view_signals [SEARCH_RESULT], 0,
status);
}
static void
-emit_folder_bar_message (EAddressbookView *eav, const gchar *message)
+emit_folder_bar_message (EABView *eav, const gchar *message)
{
g_signal_emit (eav,
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE], 0,
+ eab_view_signals [FOLDER_BAR_MESSAGE], 0,
message);
}
static void
-status_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
+status_message (GtkObject *object, const gchar *status, EABView *eav)
{
emit_status_message (eav, status);
}
static void
-search_result (GtkObject *object, EBookViewStatus status, EAddressbookView *eav)
+search_result (GtkObject *object, EBookViewStatus status, EABView *eav)
{
emit_search_result (eav, status);
}
static void
-folder_bar_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
+folder_bar_message (GtkObject *object, const gchar *status, EABView *eav)
{
emit_folder_bar_message (eav, status);
}
static void
-stop_state_changed (GtkObject *object, EAddressbookView *eav)
+stop_state_changed (GtkObject *object, EABView *eav)
{
command_state_change (eav);
}
static void
-command_state_change (EAddressbookView *eav)
+command_state_change (EABView *eav)
{
/* Reffing during emission is unnecessary. Gtk automatically refs during an emission. */
- g_signal_emit (eav, e_addressbook_view_signals [COMMAND_STATE_CHANGE], 0);
+ g_signal_emit (eav, eab_view_signals [COMMAND_STATE_CHANGE], 0);
}
static void
-alphabet_state_change (EAddressbookView *eav, gunichar letter)
-{
- g_signal_emit (eav, e_addressbook_view_signals [ALPHABET_STATE_CHANGE], 0, letter);
-}
-
-static void
-backend_died (GtkObject *object, EAddressbookView *eav)
+backend_died (GtkObject *object, EABView *eav)
{
char *message = g_strdup_printf (_("The addressbook backend for\n%s\nhas crashed. "
"You will have to restart Evolution in order "
@@ -1362,12 +1105,52 @@ backend_died (GtkObject *object, EAddressbookView *eav)
}
static void
-create_table_view (EAddressbookView *view)
+minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EABView *view)
+{
+ do_popup_menu(view, event);
+}
+
+static void
+create_minicard_view (EABView *view)
+{
+ GtkWidget *scrolled_window;
+ GtkWidget *minicard_view;
+ EAddressbookReflowAdapter *adapter;
+
+ adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model));
+ minicard_view = e_minicard_view_widget_new(adapter);
+
+ g_signal_connect(minicard_view, "selection_change",
+ G_CALLBACK(selection_changed), view);
+
+ g_signal_connect(minicard_view, "right_click",
+ G_CALLBACK(minicard_right_click), view);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ view->object = G_OBJECT(minicard_view);
+ view->widget = scrolled_window;
+
+ gtk_container_add (GTK_CONTAINER (scrolled_window), minicard_view);
+ gtk_widget_show (minicard_view);
+
+ gtk_widget_show_all( GTK_WIDGET(scrolled_window) );
+
+ gtk_paned_add1 (GTK_PANED (view->paned), scrolled_window);
+
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+}
+
+static void
+create_table_view (EABView *view)
{
ETableModel *adapter;
GtkWidget *table;
- adapter = e_addressbook_table_adapter_new(view->model);
+ adapter = eab_table_adapter_new(view->model);
/* Here we create the table. We give it the three pieces of
the table we've created, the header, the model, and the
@@ -1395,11 +1178,7 @@ create_table_view (EAddressbookView *view)
G_CALLBACK (table_drag_data_get),
view);
- gtk_table_attach(GTK_TABLE(view), table,
- 0, 1,
- 0, 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
+ gtk_paned_add1 (GTK_PANED (view->paned), table);
gtk_widget_show( GTK_WIDGET(table) );
}
@@ -1408,11 +1187,11 @@ create_table_view (EAddressbookView *view)
static void
treeview_row_activated(GtkTreeView *treeview,
GtkTreePath *path, GtkTreeViewColumn *column,
- EAddressbookView *view)
+ EABView *view)
{
- EAddressbookModel *model = view->model;
+ EABModel *model = view->model;
int row = gtk_tree_path_get_indices (path)[0];
- ECard *card = e_addressbook_model_get_card(model, row);
+ ECard *card = eab_model_get_card(model, row);
EBook *book;
g_object_get(model,
@@ -1422,16 +1201,16 @@ treeview_row_activated(GtkTreeView *treeview,
g_assert (E_IS_BOOK (book));
if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, view->editable);
+ eab_show_contact_list_editor (book, card, FALSE, view->editable);
else
- e_addressbook_show_contact_editor (book, card, FALSE, view->editable);
+ eab_show_contact_editor (book, card, FALSE, view->editable);
g_object_unref (book);
g_object_unref (card);
}
static void
-create_treeview_view (EAddressbookView *view)
+create_treeview_view (EABView *view)
{
GtkTreeModel *adapter;
ECardSimple *simple;
@@ -1441,7 +1220,7 @@ create_treeview_view (EAddressbookView *view)
simple = e_card_simple_new(NULL);
- adapter = e_addressbook_treeview_adapter_new(view->model);
+ adapter = eab_treeview_adapter_new(view->model);
scrolled = gtk_scrolled_window_new (NULL, NULL);
treeview = gtk_tree_view_new_with_model (adapter);
@@ -1490,11 +1269,7 @@ create_treeview_view (EAddressbookView *view)
g_signal_connect(e_treeview_get_selection_model (GTK_TREE_VIEW (treeview)), "selection_changed",
G_CALLBACK(selection_changed), view);
- gtk_table_attach(GTK_TABLE(view), scrolled,
- 0, 1,
- 0, 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
+ gtk_paned_add1 (GTK_PANED (view->paned), scrolled);
gtk_widget_show( GTK_WIDGET(scrolled) );
@@ -1503,26 +1278,27 @@ create_treeview_view (EAddressbookView *view)
#endif
static void
-change_view_type (EAddressbookView *view, EAddressbookViewType view_type)
+change_view_type (EABView *view, EABViewType view_type)
{
if (view_type == view->view_type)
return;
if (view->widget) {
+ gtk_container_remove (GTK_CONTAINER (view->paned), view->widget);
gtk_widget_destroy (view->widget);
view->widget = NULL;
}
view->object = NULL;
switch (view_type) {
- case E_ADDRESSBOOK_VIEW_MINICARD:
- create_minicard_view (view);
- break;
- case E_ADDRESSBOOK_VIEW_TABLE:
+ case EAB_VIEW_TABLE:
create_table_view (view);
break;
+ case EAB_VIEW_MINICARD:
+ create_minicard_view (view);
+ break;
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- case E_ADDRESSBOOK_VIEW_TREEVIEW:
+ case EAB_VIEW_TREEVIEW:
create_treeview_view (view);
break;
#endif
@@ -1614,7 +1390,7 @@ e_contact_print_button(GtkDialog *dialog, gint response, gpointer data)
}
void
-e_addressbook_view_setup_menus (EAddressbookView *view,
+eab_view_setup_menus (EABView *view,
BonoboUIComponent *uic)
{
@@ -1631,7 +1407,7 @@ e_addressbook_view_setup_menus (EAddressbookView *view,
}
/**
- * e_addressbook_view_discard_menus:
+ * eab_view_discard_menus:
* @view: An addressbook view.
*
* Makes an addressbook view discard its GAL view menus and its views instance
@@ -1639,7 +1415,7 @@ e_addressbook_view_setup_menus (EAddressbookView *view,
* deactivated.
**/
void
-e_addressbook_view_discard_menus (EAddressbookView *view)
+eab_view_discard_menus (EABView *view)
{
g_return_if_fail (view != NULL);
g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
@@ -1661,9 +1437,9 @@ e_addressbook_view_discard_menus (EAddressbookView *view)
}
void
-e_addressbook_view_print(EAddressbookView *view)
+eab_view_print(EABView *view)
{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
+ if (view->view_type == EAB_VIEW_MINICARD) {
char *query;
EBook *book;
GtkWidget *print;
@@ -1673,12 +1449,10 @@ e_addressbook_view_print(EAddressbookView *view)
"book", &book,
NULL);
print = e_contact_print_dialog_new(book, query);
-
- g_object_unref(book);
g_free(query);
gtk_widget_show_all(print);
}
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
+ else if (view->view_type == EAB_VIEW_TABLE) {
GtkWidget *dialog;
EPrintable *printable;
ETable *etable;
@@ -1709,16 +1483,16 @@ e_addressbook_view_print(EAddressbookView *view)
gtk_widget_show(dialog);
}
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TREEVIEW) {
+ else if (view->view_type == EAB_VIEW_TREEVIEW) {
/* XXX */
}
#endif
}
void
-e_addressbook_view_print_preview(EAddressbookView *view)
+eab_view_print_preview(EABView *view)
{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
+ if (view->view_type == EAB_VIEW_MINICARD) {
char *query;
EBook *book;
@@ -1727,10 +1501,9 @@ e_addressbook_view_print_preview(EAddressbookView *view)
"book", &book,
NULL);
e_contact_print_preview(book, query);
- g_object_unref(book);
g_free(query);
}
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
+ else if (view->view_type == EAB_VIEW_TABLE) {
EPrintable *printable;
ETable *etable;
GnomePrintJob *master;
@@ -1769,27 +1542,27 @@ e_addressbook_view_print_preview(EAddressbookView *view)
g_object_unref (printable);
}
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- else if (view->view_type == E_ADDRESSBOOK_VIEW_TREEVIEW) {
+ else if (view->view_type == EAB_VIEW_TREEVIEW) {
/* XXX */
}
#endif
}
void
-e_addressbook_view_delete_selection(EAddressbookView *view)
+eab_view_delete_selection(EABView *view)
{
- CardAndBook card_and_book;
+ ContactAndBook contact_and_book;
- memset (&card_and_book, 0, sizeof (card_and_book));
- card_and_book.view = view;
+ memset (&contact_and_book, 0, sizeof (contact_and_book));
+ contact_and_book.view = view;
- delete (GTK_WIDGET (view), &card_and_book);
+ delete (GTK_WIDGET (view), &contact_and_book);
}
static void
invisible_destroyed (gpointer data, GObject *where_object_was)
{
- EAddressbookView *view = data;
+ EABView *view = data;
view->invisible = NULL;
}
@@ -1798,11 +1571,11 @@ selection_get (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint info,
guint time_stamp,
- EAddressbookView *view)
+ EABView *view)
{
char *value;
- value = e_card_list_get_vcard(view->clipboard_cards);
+ value = eab_contact_list_to_string (view->clipboard_contacts);
gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
8, value, strlen (value));
@@ -1812,12 +1585,12 @@ selection_get (GtkWidget *invisible,
static void
selection_clear_event (GtkWidget *invisible,
GdkEventSelection *event,
- EAddressbookView *view)
+ EABView *view)
{
- if (view->clipboard_cards) {
- g_list_foreach (view->clipboard_cards, (GFunc)g_object_unref, NULL);
- g_list_free (view->clipboard_cards);
- view->clipboard_cards = NULL;
+ if (view->clipboard_contacts) {
+ g_list_foreach (view->clipboard_contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (view->clipboard_contacts);
+ view->clipboard_contacts = NULL;
}
}
@@ -1825,27 +1598,25 @@ static void
selection_received (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint time,
- EAddressbookView *view)
+ EABView *view)
{
if (selection_data->length < 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
return;
}
else {
/* XXX make sure selection_data->data = \0 terminated */
- GList *card_list = e_card_load_cards_from_string_with_default_charset (selection_data->data, "ISO-8859-1");
+ GList *contact_list = eab_contact_list_from_string (selection_data->data);
GList *l;
- if (!card_list /* it wasn't a vcard list */)
- return;
-
- for (l = card_list; l; l = l->next) {
- ECard *card = l->data;
+ for (l = contact_list; l; l = l->next) {
+ EContact *contact = l->data;
- e_card_merging_book_add_card (view->book, card, NULL /* XXX */, NULL);
+ /* XXX NULL for a callback /sigh */
+ eab_merging_book_add_contact (view->book, contact, NULL /* XXX */, NULL);
}
- g_list_foreach (card_list, (GFunc)g_object_unref, NULL);
- g_list_free (card_list);
+ g_list_foreach (contact_list, (GFunc)g_object_unref, NULL);
+ g_list_free (contact_list);
}
}
@@ -1857,7 +1628,7 @@ add_to_list (int model_row, gpointer closure)
}
static GList *
-get_selected_cards (EAddressbookView *view)
+get_selected_contacts (EABView *view)
{
GList *list;
GList *iterator;
@@ -1867,66 +1638,64 @@ get_selected_cards (EAddressbookView *view)
e_selection_model_foreach (selection, add_to_list, &list);
for (iterator = list; iterator; iterator = iterator->next) {
- iterator->data = e_addressbook_model_card_at (view->model, GPOINTER_TO_INT (iterator->data));
- if (iterator->data)
- g_object_ref (iterator->data);
+ iterator->data = eab_model_get_contact (view->model, GPOINTER_TO_INT (iterator->data));
}
list = g_list_reverse (list);
return list;
}
void
-e_addressbook_view_save_as (EAddressbookView *view)
+eab_view_save_as (EABView *view)
{
- GList *list = get_selected_cards (view);
+ GList *list = get_selected_contacts (view);
if (list)
- e_contact_list_save_as (_("Save as VCard"), list, NULL);
+ eab_contact_list_save (_("Save as VCard"), list, NULL);
e_free_object_list(list);
}
void
-e_addressbook_view_view (EAddressbookView *view)
+eab_view_view (EABView *view)
{
- GList *list = get_selected_cards (view);
- e_addressbook_show_multiple_cards (view->book, list, view->editable);
+ GList *list = get_selected_contacts (view);
+ eab_show_multiple_contacts (view->book, list, view->editable);
e_free_object_list(list);
}
void
-e_addressbook_view_send (EAddressbookView *view)
+eab_view_send (EABView *view)
{
- GList *list = get_selected_cards (view);
+ GList *list = get_selected_contacts (view);
if (list)
- e_addressbook_send_card_list (list, E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT);
+ eab_send_contact_list (list, EAB_DISPOSITION_AS_ATTACHMENT);
e_free_object_list(list);
}
void
-e_addressbook_view_send_to (EAddressbookView *view)
+eab_view_send_to (EABView *view)
{
- GList *list = get_selected_cards (view);
+ GList *list = get_selected_contacts (view);
if (list)
- e_addressbook_send_card_list (list, E_ADDRESSBOOK_DISPOSITION_AS_TO);
+ eab_send_contact_list (list, EAB_DISPOSITION_AS_TO);
e_free_object_list(list);
}
void
-e_addressbook_view_cut (EAddressbookView *view)
+eab_view_cut (EABView *view)
{
- e_addressbook_view_copy (view);
- e_addressbook_view_delete_selection (view);
+ eab_view_copy (view);
+ eab_view_delete_selection (view);
}
void
-e_addressbook_view_copy (EAddressbookView *view)
+eab_view_copy (EABView *view)
{
- view->clipboard_cards = get_selected_cards (view);
+ view->clipboard_contacts = get_selected_contacts (view);
gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME);
}
void
-e_addressbook_view_paste (EAddressbookView *view)
+eab_view_paste (EABView *view)
{
gtk_selection_convert (view->invisible, clipboard_atom,
GDK_SELECTION_TYPE_STRING,
@@ -1934,7 +1703,7 @@ e_addressbook_view_paste (EAddressbookView *view)
}
void
-e_addressbook_view_select_all (EAddressbookView *view)
+eab_view_select_all (EABView *view)
{
ESelectionModel *model = get_selection_model (view);
@@ -1944,7 +1713,7 @@ e_addressbook_view_select_all (EAddressbookView *view)
}
void
-e_addressbook_view_show_all(EAddressbookView *view)
+eab_view_show_all(EABView *view)
{
g_object_set(view,
"query", NULL,
@@ -1952,44 +1721,44 @@ e_addressbook_view_show_all(EAddressbookView *view)
}
void
-e_addressbook_view_stop(EAddressbookView *view)
+eab_view_stop(EABView *view)
{
if (view)
- e_addressbook_model_stop (view->model);
+ eab_model_stop (view->model);
}
static void
-view_transfer_cards (EAddressbookView *view, gboolean delete_from_source)
+view_transfer_contacts (EABView *view, gboolean delete_from_source)
{
EBook *book;
- GList *cards;
+ GList *contacts;
GtkWindow *parent_window;
g_object_get(view->model,
"book", &book,
NULL);
- cards = get_selected_cards (view);
+ contacts = get_selected_contacts (view);
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
- e_addressbook_transfer_cards (book, cards, delete_from_source, parent_window);
+ eab_transfer_contacts (book, contacts, delete_from_source, parent_window);
g_object_unref(book);
}
void
-e_addressbook_view_copy_to_folder (EAddressbookView *view)
+eab_view_copy_to_folder (EABView *view)
{
- view_transfer_cards (view, FALSE);
+ view_transfer_contacts (view, FALSE);
}
void
-e_addressbook_view_move_to_folder (EAddressbookView *view)
+eab_view_move_to_folder (EABView *view)
{
- view_transfer_cards (view, TRUE);
+ view_transfer_contacts (view, TRUE);
}
static gboolean
-e_addressbook_view_selection_nonempty (EAddressbookView *view)
+eab_view_selection_nonempty (EABView *view)
{
ESelectionModel *selection_model;
@@ -2001,85 +1770,85 @@ e_addressbook_view_selection_nonempty (EAddressbookView *view)
}
gboolean
-e_addressbook_view_can_create (EAddressbookView *view)
+eab_view_can_create (EABView *view)
{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
+ return view ? eab_model_editable (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_print (EAddressbookView *view)
+eab_view_can_print (EABView *view)
{
- return view && view->model ? e_addressbook_model_card_count (view->model) : FALSE;
+ return view && view->model ? eab_model_contact_count (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_save_as (EAddressbookView *view)
+eab_view_can_save_as (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_view (EAddressbookView *view)
+eab_view_can_view (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_send (EAddressbookView *view)
+eab_view_can_send (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_send_to (EAddressbookView *view)
+eab_view_can_send_to (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_delete (EAddressbookView *view)
+eab_view_can_delete (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
+ return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_cut (EAddressbookView *view)
+eab_view_can_cut (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
+ return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_copy (EAddressbookView *view)
+eab_view_can_copy (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_paste (EAddressbookView *view)
+eab_view_can_paste (EABView *view)
{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
+ return view ? eab_model_editable (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_select_all (EAddressbookView *view)
+eab_view_can_select_all (EABView *view)
{
- return view ? e_addressbook_model_card_count (view->model) != 0 : FALSE;
+ return view ? eab_model_contact_count (view->model) != 0 : FALSE;
}
gboolean
-e_addressbook_view_can_stop (EAddressbookView *view)
+eab_view_can_stop (EABView *view)
{
- return view ? e_addressbook_model_can_stop (view->model) : FALSE;
+ return view ? eab_model_can_stop (view->model) : FALSE;
}
gboolean
-e_addressbook_view_can_copy_to_folder (EAddressbookView *view)
+eab_view_can_copy_to_folder (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ return view ? eab_view_selection_nonempty (view) : FALSE;
}
gboolean
-e_addressbook_view_can_move_to_folder (EAddressbookView *view)
+eab_view_can_move_to_folder (EABView *view)
{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
+ return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
}
diff --git a/addressbook/gui/widgets/e-addressbook-view.etspec b/addressbook/gui/widgets/e-addressbook-view.etspec
index a0a0015d75..812a88b060 100644
--- a/addressbook/gui/widgets/e-addressbook-view.etspec
+++ b/addressbook/gui/widgets/e-addressbook-view.etspec
@@ -1,14 +1,17 @@
<ETableSpecification click-to-add="true" draw-grid="true" _click-to-add-message="* Click here to add a contact *">
- <ETableColumn model_col= "0" _title="File As" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "1" _title="Full Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "2" _title="Email" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col= "2" _title="File As" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col= "3" _title="Full Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col= "7" _title="Email" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+<!--
<ETableColumn model_col= "3" _title="Primary Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col= "4" _title="Assistant Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col= "5" _title="Business Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col= "6" _title="Callback Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col= "7" _title="Company Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col= "8" _title="Home Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "9" _title="Organization" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+-->
+ <ETableColumn model_col="21" _title="Organization" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+<!--
<ETableColumn model_col="10" _title="Business Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="11" _title="Home Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="12" _title="Mobile Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
@@ -25,19 +28,22 @@
<ETableColumn model_col="23" _title="Telex" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="24" _title="TTY" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="25" _title="Other Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="26" _title="Email 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="27" _title="Email 3" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+-->
+ <ETableColumn model_col="8" _title="Email 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="9" _title="Email 3" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="28" _title="Web Site" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="29" _title="Department" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="30" _title="Office" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="31" _title="Title" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="32" _title="Profession" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="33" _title="Manager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="34" _title="Assistant" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="22" _title="Department" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="23" _title="Office" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="24" _title="Title" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="25" _title="Profession" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="26" _title="Manager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+ <ETableColumn model_col="27" _title="Assistant" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="35" _title="Nickname" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+<!--
<ETableColumn model_col="36" _title="Spouse" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="37" _title="Note" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
<ETableColumn model_col="38" _title="Free-busy URL" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+-->
<ETableState>
<column source="0"/>
<column source="1"/>
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index dbf32811d8..1573f682ed 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -17,22 +17,20 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-#ifndef __E_ADDRESSBOOK_VIEW_H__
-#define __E_ADDRESSBOOK_VIEW_H__
+#ifndef __EAB_VIEW_H__
+#define __EAB_VIEW_H__
-#include <gtk/gtktable.h>
+#include <gtk/gtkeventbox.h>
#include <bonobo/bonobo-ui-component.h>
#include <gal/menus/gal-view-instance.h>
#include "e-addressbook-model.h"
+#include "eab-contact-display.h"
#include "widgets/menus/gal-view-menus.h"
#include "addressbook/backend/ebook/e-book.h"
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
-/* EAddressbookView - A card displaying information about a contact.
+/* EABView - A card displaying information about a contact.
*
* The following arguments are available:
*
@@ -40,36 +38,36 @@ extern "C" {
* --------------------------------------------------------------------------------
*/
-#define E_TYPE_ADDRESSBOOK_VIEW (e_addressbook_view_get_type ())
-#define E_ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookView))
-#define E_ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
-#define E_IS_ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ADDRESSBOOK_VIEW))
-#define E_IS_ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_TYPE_AB_VIEW (eab_view_get_type ())
+#define EAB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_AB_VIEW, EABView))
+#define EAB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_AB_VIEW, EABViewClass))
+#define E_IS_ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_AB_VIEW))
+#define E_IS_ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_AB_VIEW))
typedef enum {
- E_ADDRESSBOOK_VIEW_NONE, /* initialized to this */
- E_ADDRESSBOOK_VIEW_TABLE,
- E_ADDRESSBOOK_VIEW_MINICARD
+ EAB_VIEW_NONE, /* initialized to this */
+ EAB_VIEW_MINICARD,
+ EAB_VIEW_TABLE,
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
- ,E_ADDRESSBOOK_VIEW_TREEVIEW
+ ,EAB_VIEW_TREEVIEW
#endif
-} EAddressbookViewType;
+} EABViewType;
-typedef struct _EAddressbookView EAddressbookView;
-typedef struct _EAddressbookViewClass EAddressbookViewClass;
+typedef struct _EABView EABView;
+typedef struct _EABViewClass EABViewClass;
-struct _EAddressbookView
+struct _EABView
{
- GtkTable parent;
+ GtkEventBox parent;
/* item specific fields */
- EAddressbookViewType view_type;
+ EABViewType view_type;
- EAddressbookModel *model;
+ EABModel *model;
GtkWidget *invisible;
- GList *clipboard_cards;
+ GList *clipboard_contacts;
EBook *book;
char *query;
@@ -77,9 +75,10 @@ struct _EAddressbookView
GObject *object;
GtkWidget *widget;
- GtkWidget *current_alphabet_widget;
- GtkWidget *vbox;
+ GtkWidget *scrolled;
+ GtkWidget *contact_display;
+ GtkWidget *paned;
/* Menus handler and the view instance */
GalViewInstance *view_instance;
@@ -88,62 +87,58 @@ struct _EAddressbookView
BonoboUIComponent *uic;
};
-struct _EAddressbookViewClass
+struct _EABViewClass
{
- GtkTableClass parent_class;
+ GtkEventBoxClass parent_class;
/*
* Signals
*/
- void (*status_message) (EAddressbookView *view, const gchar *message);
- void (*search_result) (EAddressbookView *view, EBookViewStatus status);
- void (*folder_bar_message) (EAddressbookView *view, const gchar *message);
- void (*command_state_change) (EAddressbookView *view);
- void (*alphabet_state_change) (EAddressbookView *view, gunichar letter);
+ void (*status_message) (EABView *view, const gchar *message);
+ void (*search_result) (EABView *view, EBookViewStatus status);
+ void (*folder_bar_message) (EABView *view, const gchar *message);
+ void (*command_state_change) (EABView *view);
};
-GtkWidget *e_addressbook_view_new (void);
-GType e_addressbook_view_get_type (void);
-
-void e_addressbook_view_setup_menus (EAddressbookView *view,
- BonoboUIComponent *uic);
-
-void e_addressbook_view_discard_menus (EAddressbookView *view);
-
-void e_addressbook_view_save_as (EAddressbookView *view);
-void e_addressbook_view_view (EAddressbookView *view);
-void e_addressbook_view_send (EAddressbookView *view);
-void e_addressbook_view_send_to (EAddressbookView *view);
-void e_addressbook_view_print (EAddressbookView *view);
-void e_addressbook_view_print_preview (EAddressbookView *view);
-void e_addressbook_view_delete_selection (EAddressbookView *view);
-void e_addressbook_view_cut (EAddressbookView *view);
-void e_addressbook_view_copy (EAddressbookView *view);
-void e_addressbook_view_paste (EAddressbookView *view);
-void e_addressbook_view_select_all (EAddressbookView *view);
-void e_addressbook_view_show_all (EAddressbookView *view);
-void e_addressbook_view_stop (EAddressbookView *view);
-void e_addressbook_view_copy_to_folder (EAddressbookView *view);
-void e_addressbook_view_move_to_folder (EAddressbookView *view);
-
-gboolean e_addressbook_view_can_create (EAddressbookView *view);
-gboolean e_addressbook_view_can_print (EAddressbookView *view);
-gboolean e_addressbook_view_can_save_as (EAddressbookView *view);
-gboolean e_addressbook_view_can_view (EAddressbookView *view);
-gboolean e_addressbook_view_can_send (EAddressbookView *view);
-gboolean e_addressbook_view_can_send_to (EAddressbookView *view);
-gboolean e_addressbook_view_can_delete (EAddressbookView *view);
-gboolean e_addressbook_view_can_cut (EAddressbookView *view);
-gboolean e_addressbook_view_can_copy (EAddressbookView *view);
-gboolean e_addressbook_view_can_paste (EAddressbookView *view);
-gboolean e_addressbook_view_can_select_all (EAddressbookView *view);
-gboolean e_addressbook_view_can_stop (EAddressbookView *view);
-gboolean e_addressbook_view_can_copy_to_folder (EAddressbookView *view);
-gboolean e_addressbook_view_can_move_to_folder (EAddressbookView *view);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_ADDRESSBOOK_VIEW_H__ */
+GtkWidget *eab_view_new (void);
+GType eab_view_get_type (void);
+
+void eab_view_setup_menus (EABView *view,
+ BonoboUIComponent *uic);
+
+void eab_view_discard_menus (EABView *view);
+
+void eab_view_save_as (EABView *view);
+void eab_view_view (EABView *view);
+void eab_view_send (EABView *view);
+void eab_view_send_to (EABView *view);
+void eab_view_print (EABView *view);
+void eab_view_print_preview (EABView *view);
+void eab_view_delete_selection (EABView *view);
+void eab_view_cut (EABView *view);
+void eab_view_copy (EABView *view);
+void eab_view_paste (EABView *view);
+void eab_view_select_all (EABView *view);
+void eab_view_show_all (EABView *view);
+void eab_view_stop (EABView *view);
+void eab_view_copy_to_folder (EABView *view);
+void eab_view_move_to_folder (EABView *view);
+
+gboolean eab_view_can_create (EABView *view);
+gboolean eab_view_can_print (EABView *view);
+gboolean eab_view_can_save_as (EABView *view);
+gboolean eab_view_can_view (EABView *view);
+gboolean eab_view_can_send (EABView *view);
+gboolean eab_view_can_send_to (EABView *view);
+gboolean eab_view_can_delete (EABView *view);
+gboolean eab_view_can_cut (EABView *view);
+gboolean eab_view_can_copy (EABView *view);
+gboolean eab_view_can_paste (EABView *view);
+gboolean eab_view_can_select_all (EABView *view);
+gboolean eab_view_can_stop (EABView *view);
+gboolean eab_view_can_copy_to_folder (EABView *view);
+gboolean eab_view_can_move_to_folder (EABView *view);
+
+G_END_DECLS;
+
+#endif /* __EAB_VIEW_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-control.h b/addressbook/gui/widgets/e-minicard-control.h
deleted file mode 100644
index bc0d934384..0000000000
--- a/addressbook/gui/widgets/e-minicard-control.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __E_MINICARD_CONTROL_H__
-#define __E_MINICARD_CONTROL_H__
-
-#include <bonobo/bonobo-control.h>
-
-BonoboControl *e_minicard_control_new (void);
-
-#endif /* __E_MINICARD_CONTROL_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-label.c b/addressbook/gui/widgets/e-minicard-label.c
index 607170aea4..31935164d7 100644
--- a/addressbook/gui/widgets/e-minicard-label.c
+++ b/addressbook/gui/widgets/e-minicard-label.c
@@ -22,7 +22,7 @@
#include <config.h>
#include "e-minicard-label.h"
-#include "e-addressbook-marshal.h"
+#include "eab-marshal.h"
#include <gtk/gtksignal.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
@@ -172,7 +172,7 @@ e_minicard_label_class_init (EMinicardLabelClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EMinicardLabelClass, style_set),
NULL, NULL,
- e_addressbook_marshal_VOID__OBJECT,
+ eab_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_STYLE);
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index c90a581975..ff1bdc1f06 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -26,7 +26,7 @@
#include <gal/widgets/e-canvas.h>
#include <libgnome/gnome-i18n.h>
-#include "e-addressbook-marshal.h"
+#include "eab-marshal.h"
#include "e-minicard-view-widget.h"
static void e_minicard_view_widget_init (EMinicardViewWidget *widget);
@@ -38,7 +38,6 @@ static void e_minicard_view_widget_reflow (ECanvas *canvas);
static void e_minicard_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
static void e_minicard_view_widget_style_set (GtkWidget *widget, GtkStyle *previous_style);
static void e_minicard_view_widget_realize (GtkWidget *widget);
-static gboolean e_minicard_view_widget_real_focus_in_event (GtkWidget *widget, GdkEventFocus *event);
static ECanvasClass *parent_class = NULL;
@@ -135,7 +134,7 @@ e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardViewWidgetClass, selection_change),
NULL, NULL,
- e_addressbook_marshal_NONE__NONE,
+ eab_marshal_NONE__NONE,
G_TYPE_NONE, 0);
signals [COLUMN_WIDTH_CHANGED] =
@@ -144,7 +143,7 @@ e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardViewWidgetClass, column_width_changed),
NULL, NULL,
- e_addressbook_marshal_NONE__DOUBLE,
+ eab_marshal_NONE__DOUBLE,
G_TYPE_NONE, 1, G_TYPE_DOUBLE);
signals [RIGHT_CLICK] =
@@ -153,42 +152,18 @@ e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardViewWidgetClass, right_click),
NULL, NULL,
- e_addressbook_marshal_INT__POINTER,
+ eab_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
widget_class->style_set = e_minicard_view_widget_style_set;
widget_class->realize = e_minicard_view_widget_realize;
widget_class->size_allocate = e_minicard_view_widget_size_allocate;
- widget_class->focus_in_event = e_minicard_view_widget_real_focus_in_event;
canvas_class->reflow = e_minicard_view_widget_reflow;
klass->selection_change = NULL;
klass->column_width_changed = NULL;
klass->right_click = NULL;
-
-}
-
-static gboolean
-e_minicard_view_widget_real_focus_in_event(GtkWidget *widget, GdkEventFocus *event)
-{
- GnomeCanvas *canvas;
- EMinicardViewWidget *view;
-
- canvas = GNOME_CANVAS (widget);
- view = E_MINICARD_VIEW_WIDGET(widget);
-
- if (!canvas->focused_item) {
- EReflow *reflow = E_REFLOW (view->emv);
- if (reflow->count) {
- int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), 0);
-
- if (unsorted != -1)
- canvas->focused_item = reflow->items [unsorted];
- }
- }
-
- return GTK_WIDGET_CLASS(parent_class)->focus_in_event (widget, event);
}
static void
@@ -326,6 +301,18 @@ selection_change (ESelectionModel *esm, EMinicardViewWidget *widget)
}
static void
+selection_row_change (ESelectionModel *esm, int row, EMinicardViewWidget *widget)
+{
+ gboolean selected = e_selection_model_is_row_selected (esm, row);
+
+ /* we only handle the selected case here */
+ if (!selected)
+ return;
+
+ selection_change (esm, widget);
+}
+
+static void
column_width_changed (ESelectionModel *esm, double width, EMinicardViewWidget *widget)
{
g_signal_emit (widget,
@@ -356,6 +343,7 @@ e_minicard_view_widget_style_set (GtkWidget *widget, GtkStyle *previous_style)
GTK_WIDGET_CLASS(parent_class)->style_set (widget, previous_style);
}
+
static void
e_minicard_view_widget_realize (GtkWidget *widget)
{
@@ -379,6 +367,9 @@ e_minicard_view_widget_realize (GtkWidget *widget)
g_signal_connect (E_REFLOW(view->emv)->selection,
"selection_changed",
G_CALLBACK (selection_change), view);
+ g_signal_connect (E_REFLOW(view->emv)->selection,
+ "selection_row_changed",
+ G_CALLBACK (selection_row_change), view);
g_signal_connect (view->emv,
"column_width_changed",
G_CALLBACK (column_width_changed), view);
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index 18c4049e65..3c588c9ef2 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -23,9 +23,10 @@
#include "e-minicard-view.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
+#include "eab-marshal.h"
+#include "util/eab-book-util.h"
-#include "e-addressbook-marshal.h"
#include <gtk/gtkselection.h>
#include <gtk/gtkdnd.h>
#include <gal/widgets/e-canvas.h>
@@ -83,7 +84,7 @@ e_minicard_view_drag_data_get(GtkWidget *widget,
case DND_TARGET_TYPE_VCARD_LIST: {
char *value;
- value = e_card_list_get_vcard(view->drag_list);
+ value = eab_contact_list_to_string (view->drag_list);
gtk_selection_data_set (selection_data,
selection_data->target,
@@ -149,7 +150,7 @@ set_empty_message (EMinicardView *view)
}
static void
-writable_status_change (EAddressbookModel *model, gboolean writable, EMinicardView *view)
+writable_status_change (EABModel *model, gboolean writable, EMinicardView *view)
{
set_empty_message (view);
}
@@ -177,13 +178,12 @@ e_minicard_view_set_property (GObject *object,
case PROP_ADAPTER:
if (view->adapter) {
if (view->writable_status_id) {
- EAddressbookModel *model;
+ EABModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
if (model) {
g_signal_handler_disconnect (model, view->writable_status_id);
- g_object_unref (model);
}
}
@@ -197,7 +197,7 @@ e_minicard_view_set_property (GObject *object,
"model", view->adapter,
NULL);
if (view->adapter) {
- EAddressbookModel *model;
+ EABModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
@@ -277,13 +277,12 @@ e_minicard_view_dispose (GObject *object)
if (view->adapter) {
if (view->writable_status_id) {
- EAddressbookModel *model;
+ EABModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
if (model) {
g_signal_handler_disconnect (model, view->writable_status_id);
- g_object_unref (model);
}
}
@@ -323,10 +322,8 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
EBook *book;
g_object_get(view, "book", &book, NULL);
- if (book && E_IS_BOOK (book)) {
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, editable);
- g_object_unref (book);
- }
+ if (book && E_IS_BOOK (book))
+ eab_show_contact_editor (book, e_contact_new(), TRUE, editable);
}
return TRUE;
}
@@ -391,7 +388,7 @@ static void
do_remove (int i, gpointer user_data)
{
EBook *book;
- ECard *card;
+ EContact *contact;
ViewCbClosure *viewcbclosure = user_data;
EMinicardView *view = viewcbclosure->view;
EBookCallback cb = viewcbclosure->cb;
@@ -401,12 +398,11 @@ do_remove (int i, gpointer user_data)
"book", &book,
NULL);
- card = e_addressbook_reflow_adapter_get_card (view->adapter, i);
+ contact = e_addressbook_reflow_adapter_get_contact (view->adapter, i);
- e_book_remove_card(book, card, cb, closure);
+ e_book_async_remove_contact(book, contact, cb, closure);
- g_object_unref (card);
- g_object_unref (book);
+ g_object_unref (contact);
}
#if 0
@@ -425,13 +421,13 @@ compare_to_utf_str (EMinicard *card, const char *utf_str)
g_object_get(card->card,
"file_as", &file_as,
NULL);
- if (file_as) {
- int cmp = g_utf8_strcasecmp (file_as, utf_str);
- g_free (file_as);
- return cmp;
- }
+ if (file_as)
+ return g_utf8_strcasecmp (file_as, utf_str);
+ else
+ return 0;
+ } else {
+ return 0;
}
- return 0;
}
#endif
@@ -486,7 +482,7 @@ e_minicard_view_class_init (EMinicardViewClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardViewClass, right_click),
NULL, NULL,
- e_addressbook_marshal_INT__POINTER,
+ eab_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
item_class->event = e_minicard_view_event;
@@ -567,7 +563,7 @@ static void
add_to_list (int index, gpointer closure)
{
ModelAndList *mal = closure;
- mal->list = g_list_prepend (mal->list, e_addressbook_reflow_adapter_get_card (mal->adapter, index));
+ mal->list = g_list_prepend (mal->list, e_addressbook_reflow_adapter_get_contact (mal->adapter, index));
}
GList *
diff --git a/addressbook/gui/widgets/e-minicard-widget-test.c b/addressbook/gui/widgets/e-minicard-widget-test.c
deleted file mode 100644
index 9a8d27d21c..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget-test.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#define TEST_VCARD \
-"BEGIN:VCARD
-" \
-"FN:Nat
-" \
-"N:Friedman;Nat;D;Mr.
-" \
-"ORG:Ximian, Inc.
-" \
-"TITLE:Head Geek
-" \
-"ROLE:Programmer/Executive
-" \
-"BDAY:1977-08-06
-" \
-"TEL;WORK:617 679 1984
-" \
-"TEL;CELL:123 456 7890
-" \
-"EMAIL;INTERNET:nat@nat.org
-" \
-"EMAIL;INTERNET:nat@ximian.com
-" \
-"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;
-" \
-"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA
-" \
-"END:VCARD
-" \
-"
-"
-
-#include "config.h"
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include "e-minicard-widget.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-
-static void destroy_callback(gpointer data, GObject *where_object_was)
-{
- exit(0);
-}
-
-#if 0
-static void about_callback( GtkWidget *widget, gpointer data )
-{
-
- const gchar *authors[] =
- {
- "Christopher James Lahey <clahey@umich.edu>",
- NULL
- };
-
- GtkWidget *about =
- gnome_about_new ( _( "Minicard Widget Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard widget" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *minicard;
- ECard *card;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Widget Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Widget Test", NULL);
-
- minicard = e_minicard_widget_new();
- card = e_card_new(TEST_VCARD);
- g_object_set(minicard,
- "card", card,
- NULL);
-
- gnome_app_set_contents( GNOME_APP( app ), minicard );
-
- /* Connect the signals */
- g_object_weak_ref (app, destroy_callback, app);
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/e-minicard-widget.c b/addressbook/gui/widgets/e-minicard-widget.c
deleted file mode 100644
index e8f33673c3..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-table-field-chooser.c
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "e-minicard-widget.h"
-#include "e-minicard.h"
-
-static void e_minicard_widget_init (EMinicardWidget *card);
-static void e_minicard_widget_class_init (EMinicardWidgetClass *klass);
-static void e_minicard_widget_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_minicard_widget_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static void e_minicard_widget_dispose (GObject *object);
-static void e_minicard_widget_size_request (GtkWidget *widget, GtkRequisition *requisition);
-static void e_minicard_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static void e_minicard_widget_reflow (ECanvas *canvas);
-
-static ECanvasClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- PROP_0,
- PROP_CARD,
-};
-
-GType
-e_minicard_widget_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMinicardWidgetClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_minicard_widget_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMinicardWidget),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_minicard_widget_init,
- };
-
- type = g_type_register_static (e_canvas_get_type (), "EMinicardWidget", &info, 0);
- }
-
- return type;
-}
-
-static void
-e_minicard_widget_class_init (EMinicardWidgetClass *klass)
-{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECanvasClass *ecanvas_class;
-
- object_class = G_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
- ecanvas_class = E_CANVAS_CLASS(klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->set_property = e_minicard_widget_set_property;
- object_class->get_property = e_minicard_widget_get_property;
- object_class->dispose = e_minicard_widget_dispose;
-
- widget_class->size_request = e_minicard_widget_size_request;
- widget_class->size_allocate = e_minicard_widget_size_allocate;
-
- ecanvas_class->reflow = e_minicard_widget_reflow;
-
- g_object_class_install_property (object_class, PROP_CARD,
- g_param_spec_object ("card",
- _("Card"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_CARD,
- G_PARAM_READWRITE));
-}
-
-static void
-e_minicard_widget_size_request(GtkWidget *widget, GtkRequisition *requisition)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(widget);
- g_object_get(emw->item,
- "height", &height,
- NULL);
- if (height <= 0)
- height = 1;
- widget->requisition.height = height;
- widget->requisition.width = 200;
- requisition->height = height;
- requisition->width = 200;
-}
-
-static void
-e_minicard_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(widget);
- gnome_canvas_item_set( emw->item,
- "width", (double) allocation->width,
- NULL );
- g_object_get(emw->item,
- "height", &height,
- NULL);
- height = MAX(height, allocation->height);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( emw ), 0, 0, allocation->width - 1, height - 1);
- gnome_canvas_item_set( emw->rect,
- "x2", (double) allocation->width,
- "y2", (double) height,
- NULL );
- if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
- GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
-}
-
-static void e_minicard_widget_reflow(ECanvas *canvas)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(canvas);
- g_object_get(emw->item,
- "height", &height,
- NULL);
-
- height = MAX(height, GTK_WIDGET(emw)->allocation.height);
-
- gnome_canvas_set_scroll_region (GNOME_CANVAS(emw), 0, 0, GTK_WIDGET(emw)->allocation.width - 1, height - 1);
- gnome_canvas_item_set( emw->rect,
- "x2", (double) GTK_WIDGET(emw)->allocation.width,
- "y2", (double) height,
- NULL );
-
- gtk_widget_queue_resize(GTK_WIDGET(canvas));
-}
-
-static void
-e_minicard_widget_init (EMinicardWidget *emw)
-{
- emw->rect = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(emw)),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
-
- emw->item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(emw)),
- e_minicard_get_type(),
- "width", (double) 100,
- NULL );
-
-#if PENDING_PORT_WORK
- /* XXX this crashes since the canvas has no h/v adjustments. */
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( emw ),
- 0, 0,
- 100, 100 );
-#endif
- emw->card = NULL;
-}
-
-static void
-e_minicard_widget_dispose (GObject *object)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- if (emw->card) {
- g_object_unref (emw->card);
- emw->card = NULL;
- }
-
- if (G_OBJECT_CLASS(parent_class)->dispose)
- G_OBJECT_CLASS(parent_class)->dispose(object);
-}
-
-GtkWidget*
-e_minicard_widget_new (void)
-{
- GtkWidget *widget = GTK_WIDGET (g_object_new (E_TYPE_MINICARD_WIDGET, NULL));
- return widget;
-}
-
-static void
-e_minicard_widget_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
- gpointer ptr;
-
- switch (prop_id){
- case PROP_CARD:
- ptr = g_value_get_object (value);
- e_minicard_widget_set_card (emw, ptr ? E_CARD (ptr) : NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-e_minicard_widget_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- switch (prop_id) {
- case PROP_CARD:
- if (emw->card)
- g_value_set_object (value, emw->card);
- else
- g_value_set_object (value, NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-void
-e_minicard_widget_set_card (EMinicardWidget *emw, ECard *card)
-{
- g_return_if_fail (emw && E_IS_MINICARD_WIDGET (emw));
- g_return_if_fail (card == NULL || E_IS_CARD (card));
-
- if (card != emw->card) {
-
- if (emw->card)
- g_object_unref (emw->card);
-
- emw->card = card;
-
- if (emw->card)
- g_object_ref (emw->card);
-
- if (emw->item)
- g_object_set (emw->item,
- "card", emw->card,
- NULL);
- }
-}
diff --git a/addressbook/gui/widgets/e-minicard-widget.h b/addressbook/gui/widgets/e-minicard-widget.h
deleted file mode 100644
index 829ad8f77d..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-widget.h
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __E_MINICARD_WIDGET_H__
-#define __E_MINICARD_WIDGET_H__
-
-#include <gal/widgets/e-canvas.h>
-#include "addressbook/backend/ebook/e-card.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EMinicardWidget - A card displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- */
-
-#define E_TYPE_MINICARD_WIDGET (e_minicard_widget_get_type ())
-#define E_MINICARD_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_WIDGET, EMinicardWidget))
-#define E_MINICARD_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_WIDGET, EMinicardWidgetClass))
-#define E_IS_MINICARD_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_WIDGET))
-#define E_IS_MINICARD_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_WIDGET))
-
-
-typedef struct _EMinicardWidget EMinicardWidget;
-typedef struct _EMinicardWidgetClass EMinicardWidgetClass;
-
-struct _EMinicardWidget
-{
- ECanvas parent;
-
- /* item specific fields */
- GnomeCanvasItem *item;
-
- GnomeCanvasItem *rect;
- ECard *card;
-};
-
-struct _EMinicardWidgetClass
-{
- ECanvasClass parent_class;
-};
-
-
-GtkWidget *e_minicard_widget_new(void);
-GType e_minicard_widget_get_type (void);
-
-void e_minicard_widget_set_card (EMinicardWidget *, ECard *);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_MINICARD_WIDGET_H__ */
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index 7ce6d2f518..f9aa893dc3 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -33,14 +33,13 @@
#include <gal/widgets/e-canvas-utils.h>
#include <gal/widgets/e-canvas.h>
#include "addressbook/backend/ebook/e-book.h"
-#include "e-addressbook-marshal.h"
-#include "e-addressbook-util.h"
+#include "eab-marshal.h"
+#include "eab-gui-util.h"
#include "e-minicard.h"
#include "e-minicard-label.h"
#include "e-minicard-view.h"
#include "e-contact-editor.h"
-#include "e-card-merging.h"
-#include "ebook/e-destination.h"
+#include "util/eab-destination.h"
static void e_minicard_init (EMinicard *card);
static void e_minicard_class_init (EMinicardClass *klass);
@@ -64,7 +63,7 @@ static GnomeCanvasGroupClass *parent_class = NULL;
typedef struct _EMinicardField EMinicardField;
struct _EMinicardField {
- ECardSimpleField field;
+ EContactField field;
GnomeCanvasItem *label;
};
@@ -90,7 +89,7 @@ enum {
PROP_SELECTED,
PROP_HAS_CURSOR,
PROP_EDITABLE,
- PROP_CARD
+ PROP_CONTACT
};
enum {
@@ -185,11 +184,11 @@ e_minicard_class_init (EMinicardClass *klass)
FALSE,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class, PROP_CARD,
- g_param_spec_object ("card",
- _("Card"),
+ g_object_class_install_property (object_class, PROP_CONTACT,
+ g_param_spec_object ("contact",
+ _("Contact"),
/*_( */"XXX blurb" /*)*/,
- E_TYPE_CARD,
+ E_TYPE_CONTACT,
G_PARAM_READWRITE));
e_minicard_signals [SELECTED] =
@@ -198,7 +197,7 @@ e_minicard_class_init (EMinicardClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardClass, selected),
NULL, NULL,
- e_addressbook_marshal_INT__POINTER,
+ eab_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
e_minicard_signals [DRAG_BEGIN] =
@@ -207,7 +206,7 @@ e_minicard_class_init (EMinicardClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EMinicardClass, drag_begin),
NULL, NULL,
- e_addressbook_marshal_INT__POINTER,
+ eab_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
e_minicard_signals [STYLE_SET] =
@@ -216,7 +215,7 @@ e_minicard_class_init (EMinicardClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EMinicardClass, style_set),
NULL, NULL,
- e_addressbook_marshal_VOID__OBJECT,
+ eab_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_STYLE);
@@ -231,7 +230,6 @@ e_minicard_class_init (EMinicardClass *klass)
static void
e_minicard_init (EMinicard *minicard)
{
- /* minicard->card = NULL;*/
minicard->rect = NULL;
minicard->fields = NULL;
minicard->width = 10;
@@ -241,8 +239,7 @@ e_minicard_init (EMinicard *minicard)
minicard->editable = FALSE;
minicard->has_cursor = FALSE;
- minicard->card = NULL;
- minicard->simple = e_card_simple_new(NULL);
+ minicard->contact = NULL;
minicard->list_icon_pixbuf = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" LIST_ICON_FILENAME, NULL);
minicard->list_icon_size = gdk_pixbuf_get_height (minicard->list_icon_pixbuf);
@@ -344,15 +341,12 @@ e_minicard_set_property (GObject *object, guint prop_id, const GValue *value, G
if (e_minicard->has_cursor != g_value_get_boolean (value))
set_has_cursor (e_minicard, g_value_get_boolean (value));
break;
- case PROP_CARD:
- if (e_minicard->card)
- g_object_unref (e_minicard->card);
- e_minicard->card = E_CARD(g_value_get_object (value));
- if (e_minicard->card)
- g_object_ref (e_minicard->card);
- g_object_set(e_minicard->simple,
- "card", e_minicard->card,
- NULL);
+ case PROP_CONTACT:
+ if (e_minicard->contact)
+ g_object_unref (e_minicard->contact);
+ e_minicard->contact = E_CONTACT(g_value_get_object (value));
+ if (e_minicard->contact)
+ g_object_ref (e_minicard->contact);
remodel(e_minicard);
e_canvas_item_request_reflow(item);
e_minicard->changed = FALSE;
@@ -389,9 +383,8 @@ e_minicard_get_property (GObject *object, guint prop_id, GValue *value, GParamS
case PROP_EDITABLE:
g_value_set_boolean (value, e_minicard->editable);
break;
- case PROP_CARD:
- e_card_simple_sync_card(e_minicard->simple);
- g_value_set_object (value, e_minicard->card);
+ case PROP_CONTACT:
+ g_value_set_object (value, e_minicard->contact);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -436,10 +429,8 @@ e_minicard_finalize (GObject *object)
e_minicard = E_MINICARD (object);
- if (e_minicard->card)
- g_object_unref (e_minicard->card);
- if (e_minicard->simple)
- g_object_unref (e_minicard->simple);
+ if (e_minicard->contact)
+ g_object_unref (e_minicard->contact);
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
@@ -523,14 +514,6 @@ e_minicard_unrealize (GnomeCanvasItem *item)
(* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
}
-static void
-card_modified_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- d(g_print ("%s: %s(): a card was modified\n", __FILE__, G_GNUC_FUNCTION));
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
-}
-
/* Callback used when the contact editor is closed */
static void
editor_closed_cb (GtkObject *editor, gpointer data)
@@ -560,35 +543,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
if (!e_minicard->selected) {
e_minicard_selected(e_minicard, event);
}
- } else {
- EBook *book = NULL;
-
- if (e_minicard->changed) {
-
- e_card_simple_sync_card(e_minicard->simple);
-
- if (E_IS_MINICARD_VIEW(GNOME_CANVAS_ITEM(e_minicard)->parent)) {
-
- g_object_get(GNOME_CANVAS_ITEM(e_minicard)->parent,
- "book", &book,
- NULL);
-
- }
-
- if (book) {
-
- /* Add the card in the contact editor to our ebook */
- e_card_merging_book_commit_card (book,
- e_minicard->card,
- card_modified_cb,
- NULL);
- g_object_unref(book);
- } else {
- remodel(e_minicard);
- e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(e_minicard));
- }
- e_minicard->changed = FALSE;
- }
+ }
+ else {
e_minicard->has_focus = FALSE;
}
}
@@ -651,7 +607,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
case GDK_2BUTTON_PRESS:
if (event->button.button == 1 && E_IS_MINICARD_VIEW(item->parent)) {
if (e_minicard->editor) {
- if (e_card_evolution_list (e_minicard->card))
+ if (GPOINTER_TO_INT (e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST)))
e_contact_list_editor_raise (E_CONTACT_LIST_EDITOR(e_minicard->editor));
else
e_contact_editor_raise(E_CONTACT_EDITOR(e_minicard->editor));
@@ -664,14 +620,14 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
}
if (book != NULL) {
- if (e_card_evolution_list (e_minicard->card)) {
- EContactListEditor *editor = e_addressbook_show_contact_list_editor (book, e_minicard->card,
- FALSE, e_minicard->editable);
+ if (e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST)) {
+ EContactListEditor *editor = eab_show_contact_list_editor (book, e_minicard->contact,
+ FALSE, e_minicard->editable);
e_minicard->editor = G_OBJECT (editor);
}
else {
- EContactEditor *editor = e_addressbook_show_contact_editor (book, e_minicard->card,
- FALSE, e_minicard->editable);
+ EContactEditor *editor = eab_show_contact_editor (book, e_minicard->contact,
+ FALSE, e_minicard->editable);
e_minicard->editor = G_OBJECT (editor);
}
g_object_ref (e_minicard->editor);
@@ -685,36 +641,6 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
return TRUE;
}
break;
- case GDK_KEY_PRESS:
- if (event->key.keyval == GDK_Tab ||
- event->key.keyval == GDK_KP_Tab ||
- event->key.keyval == GDK_ISO_Left_Tab) {
- GList *list;
- for (list = e_minicard->fields; list; list = list->next) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
- GnomeCanvasItem *item = field->label;
- EFocus has_focus;
- g_object_get(item,
- "has_focus", &has_focus,
- NULL);
- if (has_focus != E_FOCUS_NONE) {
- if (event->key.state & GDK_SHIFT_MASK)
- list = list->prev;
- else
- list = list->next;
- if (list) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
- GnomeCanvasItem *item = field->label;
- gnome_canvas_item_set(item,
- "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
- NULL);
- return 1;
- } else {
- return 0;
- }
- }
- }
- }
default:
break;
}
@@ -729,11 +655,12 @@ static void
e_minicard_resize_children( EMinicard *e_minicard )
{
GList *list;
-
+ gboolean is_list = GPOINTER_TO_INT (e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST));
+
if (e_minicard->header_text) {
gnome_canvas_item_set( e_minicard->header_text,
"width", ((double) e_minicard->width - 12
- - (e_card_evolution_list (e_minicard->card) ? e_minicard->list_icon_size : 0.0)),
+ - (is_list ? e_minicard->list_icon_size : 0.0)),
NULL );
}
if (e_minicard->list_icon) {
@@ -749,79 +676,24 @@ e_minicard_resize_children( EMinicard *e_minicard )
}
static void
-field_changed (EText *text, EMinicard *e_minicard)
-{
- ECardSimpleType type;
- char *string;
- char *new_string;
- gboolean is_list = FALSE;
-
- type = GPOINTER_TO_INT
- (g_object_get_data(G_OBJECT(text),
- "EMinicard:field"));
- g_object_get(text,
- "text", &string,
- NULL);
-
- /*
- * If the card is coresponding with a contact list and the field be
- * changed is e-mail address, should wrap it before write it back.
- */
- new_string = (char*)e_card_simple_get_const (e_minicard->simple,
- E_CARD_SIMPLE_FIELD_IS_LIST);
-
- is_list = (NULL != new_string);
-
- if (is_list && (E_CARD_SIMPLE_FIELD_EMAIL == type ||
- E_CARD_SIMPLE_FIELD_EMAIL_2 == type ||
- E_CARD_SIMPLE_FIELD_EMAIL_3 == type)) {
- if (string && *string) {
- EDestination *dest = e_destination_new ();
- if (dest != NULL){
- e_destination_set_email (dest, string);
- new_string = e_destination_export(dest);
- g_free(string);
- string=new_string;
- g_object_unref (dest);
- }
- }
- }
-
- e_card_simple_set(e_minicard->simple,
- type,
- string);
- g_free(string);
- e_minicard->changed = TRUE;
-}
-
-static void
-field_activated (EText *text, EMinicard *e_minicard)
-{
- e_text_stop_editing (text);
- e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (e_minicard), FALSE);
-}
-
-static void
-add_field (EMinicard *e_minicard, ECardSimpleField field, gdouble left_width)
+add_field (EMinicard *e_minicard, EContactField field, gdouble left_width)
{
GnomeCanvasItem *new_item;
GnomeCanvasGroup *group;
- ECardSimpleType type;
EMinicardField *minicard_field;
char *name;
char *string;
group = GNOME_CANVAS_GROUP( e_minicard );
- type = e_card_simple_type(e_minicard->simple, field);
- name = g_strdup_printf("%s:", e_card_simple_get_name(e_minicard->simple, field));
- string = e_card_simple_get(e_minicard->simple, field);
+ name = g_strdup_printf("%s:", e_contact_pretty_name (field));
+ string = e_contact_get (e_minicard->contact, field);
/* Magically convert embedded XML into an address. */
if (!strncmp (string, "<?xml", 5)) {
- EDestination *dest = e_destination_import (string);
+ EABDestination *dest = eab_destination_import (string);
if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_textrep (dest, TRUE));
+ gchar *new_string = g_strdup (eab_destination_get_textrep (dest, TRUE));
g_free (string);
string = new_string;
g_object_unref (dest);
@@ -834,15 +706,13 @@ add_field (EMinicard *e_minicard, ECardSimpleField field, gdouble left_width)
"fieldname", name,
"field", string,
"max_field_name_length", left_width,
- "editable", e_minicard->editable,
+ "editable", FALSE,
NULL );
- g_signal_connect(E_MINICARD_LABEL(new_item)->field,
- "changed", G_CALLBACK (field_changed), e_minicard);
- g_signal_connect(E_MINICARD_LABEL(new_item)->field,
- "activate", G_CALLBACK (field_activated), e_minicard);
+#if notyet
g_object_set(E_MINICARD_LABEL(new_item)->field,
- "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->simple, field),
+ "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->contact, field),
NULL);
+#endif
g_object_set_data(G_OBJECT (E_MINICARD_LABEL(new_item)->field),
"EMinicard:field",
GINT_TO_POINTER(field));
@@ -861,14 +731,18 @@ static int
get_left_width(EMinicard *e_minicard)
{
gchar *name;
- ECardSimpleField field;
+ EContactField field;
int width = -1;
PangoLayout *layout;
layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas), "");
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST; field++) {
+ for(field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
int this_width;
- name = g_strdup_printf("%s:", e_card_simple_get_name(e_minicard->simple, field));
+
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
+ continue;
+
+ name = g_strdup_printf("%s:", e_contact_pretty_name (field));
pango_layout_set_text (layout, name, -1);
pango_layout_get_pixel_size (layout, &this_width, NULL);
if (width < this_width)
@@ -885,46 +759,47 @@ remodel( EMinicard *e_minicard )
int count = 0;
if ( !(GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED) )
return;
- if (e_minicard->simple) {
- ECardSimpleField field;
+ if (e_minicard->contact) {
+ EContactField field;
GList *list;
char *file_as;
int left_width = -1;
if (e_minicard->header_text) {
- file_as = e_card_simple_get(e_minicard->simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- gnome_canvas_item_set( e_minicard->header_text,
+ file_as = e_contact_get (e_minicard->contact, E_CONTACT_FILE_AS);
+ gnome_canvas_item_set (e_minicard->header_text,
"text", file_as ? file_as : "",
NULL );
g_free(file_as);
}
- if (e_minicard->card && e_card_evolution_list (e_minicard->card) ) {
+ if (e_minicard->contact && e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST))
gnome_canvas_item_show (e_minicard->list_icon);
- }
- else {
+ else
gnome_canvas_item_hide (e_minicard->list_icon);
- }
list = e_minicard->fields;
e_minicard->fields = NULL;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING && count < 5; field++) {
+ for(field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING && count < 5; field++) {
EMinicardField *minicard_field = NULL;
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
+ continue;
+
if (list)
minicard_field = list->data;
if (minicard_field && minicard_field->field == field) {
GList *this_list = list;
char *string;
- string = e_card_simple_get(e_minicard->simple, field);
+ string = e_contact_get(e_minicard->contact, field);
if (string && *string) {
/* Magically convert embedded XML into an address. */
if (!strncmp (string, "<?xml", 4)) {
- EDestination *dest = e_destination_import (string);
+ EABDestination *dest = eab_destination_import (string);
if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_textrep (dest, TRUE));
+ gchar *new_string = g_strdup (eab_destination_get_textrep (dest, TRUE));
g_free (string);
string = new_string;
g_object_unref (dest);
@@ -948,7 +823,7 @@ remodel( EMinicard *e_minicard )
left_width = get_left_width(e_minicard);
}
- string = e_card_simple_get(e_minicard->simple, field);
+ string = e_contact_get(e_minicard->contact, field);
if (string && *string) {
add_field(e_minicard, field, left_width);
count++;
@@ -1013,8 +888,8 @@ e_minicard_get_card_id (EMinicard *minicard)
g_return_val_if_fail(minicard != NULL, NULL);
g_return_val_if_fail(E_IS_MINICARD(minicard), NULL);
- if (minicard->card) {
- return e_card_get_id(minicard->card);
+ if (minicard->contact) {
+ return e_contact_get_const (minicard->contact, E_CONTACT_UID);
} else {
return "";
}
@@ -1030,13 +905,12 @@ e_minicard_compare (EMinicard *minicard1, EMinicard *minicard2)
g_return_val_if_fail(minicard2 != NULL, 0);
g_return_val_if_fail(E_IS_MINICARD(minicard2), 0);
- if (minicard1->card && minicard2->card) {
+ if (minicard1->contact && minicard2->contact) {
char *file_as1, *file_as2;
-
- g_object_get(minicard1->card,
+ g_object_get(minicard1->contact,
"file_as", &file_as1,
NULL);
- g_object_get(minicard2->card,
+ g_object_get(minicard2->contact,
"file_as", &file_as2,
NULL);
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index ac0f82e46c..e4673fe4d9 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -23,8 +23,7 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "addressbook/gui/contact-editor/e-contact-editor.h"
#include <libgnomecanvas/gnome-canvas.h>
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include "addressbook/backend/ebook/e-contact.h"
#ifdef __cplusplus
extern "C" {
@@ -63,8 +62,7 @@ struct _EMinicard
GnomeCanvasGroup parent;
/* item specific fields */
- ECard *card;
- ECardSimple *simple;
+ EContact *contact;
GnomeCanvasItem *rect;
GnomeCanvasItem *header_rect;
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
new file mode 100644
index 0000000000..3de6eac380
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -0,0 +1,486 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "eab-contact-display.h"
+
+#include "e-util/e-html-utils.h"
+#include "util/eab-destination.h"
+
+#include <string.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-url.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+
+#define PARENT_TYPE (gtk_vbox_get_type ())
+
+struct _EABContactDisplayPrivate {
+ GtkHTML *html;
+ EContact *contact;
+};
+
+
+#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
+ "<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n</head>\n"
+
+#define MAX_COMPACT_IMAGE_DIMENSION 48
+
+static void
+on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle,
+ EABContactDisplay *display)
+{
+ printf ("on_url_requested (%s)\n", url);
+ if (!strcmp (url, "internal-contact-photo:")) {
+ EContactPhoto *photo;
+
+ photo = e_contact_get (display->priv->contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (display->priv->contact, E_CONTACT_LOGO);
+
+ printf ("writing a photo of length %d\n", photo->length);
+
+ gtk_html_stream_write (handle, photo->data, photo->length);
+
+ gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
+ }
+}
+
+static void
+on_link_clicked (GtkHTML *html, const char *url, EABContactDisplay *display)
+{
+ GError *err = NULL;
+
+ gnome_url_show (url, &err);
+
+ if (err) {
+ g_warning ("gnome_url_show: %s", err->message);
+ g_error_free (err);
+ }
+}
+
+static void
+render_address (GtkHTMLStream *html_stream, EContact *contact, const char *html_label, EContactField adr_field, EContactField label_field)
+{
+ EContactAddress *adr;
+ const char *label;
+
+ label = e_contact_get_const (contact, label_field);
+ if (label) {
+ char *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL);
+
+ gtk_html_stream_printf (html_stream, "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr valign=\"top\"><td>");
+ gtk_html_stream_printf (html_stream, "<b>%s:</b>&nbsp;<td>%s<br>", html_label, html);
+
+ gtk_html_stream_printf (html_stream, "<a href=\"http://www.mapquest.com/\">%s</a>", _("Map It"));
+ gtk_html_stream_printf (html_stream, "</td></tr></table>");
+ g_free (html);
+ return;
+ }
+
+ adr = e_contact_get (contact, adr_field);
+ if (adr &&
+ (adr->po || adr->ext || adr->street || adr->locality || adr->region || adr->code || adr->country)) {
+
+ gtk_html_stream_printf (html_stream, "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr valign=\"top\"><td>");
+ gtk_html_stream_printf (html_stream, "<b>%s:</b>&nbsp;<td>", html_label);
+
+ if (adr->po && *adr->po) gtk_html_stream_printf (html_stream, "%s<br>", adr->po);
+ if (adr->ext && *adr->ext) gtk_html_stream_printf (html_stream, "%s<br>", adr->ext);
+ if (adr->street && *adr->street) gtk_html_stream_printf (html_stream, "%s<br>", adr->street);
+ if (adr->locality && *adr->locality) gtk_html_stream_printf (html_stream, "%s<br>", adr->locality);
+ if (adr->region && *adr->region) gtk_html_stream_printf (html_stream, "%s<br>", adr->region);
+ if (adr->code && *adr->code) gtk_html_stream_printf (html_stream, "%s<br>", adr->code);
+ if (adr->country && *adr->country) gtk_html_stream_printf (html_stream, "%s<br>", adr->country);
+
+ gtk_html_stream_printf (html_stream, "<a href=\"http://www.mapquest.com/\">%s</a>", _("Map It"));
+ gtk_html_stream_printf (html_stream, "</td></tr></table>");
+ }
+ if (adr)
+ e_contact_address_free (adr);
+}
+
+static void
+render_string (GtkHTMLStream *html_stream, EContact *contact, const char *html_label, EContactField field)
+{
+ const char *str;
+
+ str = e_contact_get_const (contact, field);
+
+ if (str && *str) {
+ char *html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>", html_label, str);
+ g_free (html);
+ }
+}
+
+static void
+render_url (GtkHTMLStream *html_stream, EContact *contact, const char *html_label, EContactField field)
+{
+ const char *str;
+ str = e_contact_get_const (contact, field);
+ if (str && *str) {
+ char *html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>",
+ html_label, html);
+ g_free (html);
+ }
+}
+
+static void
+eab_contact_display_render_normal (EABContactDisplay *display, EContact *contact)
+{
+ GtkHTMLStream *html_stream;
+
+ if (display->priv->contact)
+ g_object_unref (display->priv->contact);
+ display->priv->contact = contact;
+ if (display->priv->contact)
+ g_object_ref (display->priv->contact);
+
+ html_stream = gtk_html_begin (display->priv->html);
+ gtk_html_stream_write (html_stream, HTML_HEADER, sizeof (HTML_HEADER) - 1);
+ gtk_html_stream_write (html_stream, "<body>\n", 7);
+
+ if (contact) {
+ char *str, *html;
+ EContactPhoto *photo;
+
+ gtk_html_stream_printf (html_stream, "<table border=\"0\" valign=\"top\"><tr valign=\"top\"><td>");
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+ if (photo) {
+ gtk_html_stream_printf (html_stream, "<img src=\"internal-contact-photo:\">");
+ e_contact_photo_free (photo);
+ }
+
+ gtk_html_stream_printf (html_stream, "</td><td>\n");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<h2>%s</h2>", html);
+ g_free (html);
+ }
+ else {
+ str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<h2>%s</h2>", html);
+ g_free (html);
+ }
+ }
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ GList *email_list;
+ GList *l;
+
+ gtk_html_stream_printf (html_stream, "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr valign=\"top\"><td>");
+ gtk_html_stream_printf (html_stream, "<b>%s:</b>&nbsp;<td>", _("List Members"));
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+ for (l = email_list; l; l = l->next) {
+ EABDestination *dest = eab_destination_import (l->data);
+ if (dest) {
+ const char *textrep = eab_destination_get_textrep (dest, TRUE);
+ char *html = e_text_to_html (textrep, 0);
+ gtk_html_stream_printf (html_stream, "%s<br>", html);
+ g_free (html);
+ g_object_unref (dest);
+ }
+ }
+ gtk_html_stream_printf (html_stream, "</td></tr></table>");
+ }
+ else {
+ render_string (html_stream, contact, _("Job Title"), E_CONTACT_TITLE);
+
+ render_string (html_stream, contact, _("Email"), E_CONTACT_EMAIL_1);
+ render_string (html_stream, contact, _("Email"), E_CONTACT_EMAIL_2);
+ render_string (html_stream, contact, _("Email"), E_CONTACT_EMAIL_3);
+
+
+ render_address (html_stream, contact, _("Home Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME);
+ render_address (html_stream, contact, _("Work Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK);
+ render_address (html_stream, contact, _("Other Address"), E_CONTACT_ADDRESS_OTHER, E_CONTACT_ADDRESS_LABEL_OTHER);
+
+ gtk_html_stream_printf (html_stream, "<hr>");
+
+ render_url (html_stream, contact, _("Home page"), E_CONTACT_HOMEPAGE_URL);
+ render_url (html_stream, contact, _("Blog"), E_CONTACT_BLOG_URL);
+
+ }
+
+ gtk_html_stream_printf (html_stream, "</td></tr></table>\n");
+ }
+
+ gtk_html_stream_write (html_stream, "</body></html>\n", 15);
+ gtk_html_end (display->priv->html, html_stream, GTK_HTML_STREAM_OK);
+}
+
+static void
+eab_contact_display_render_compact (EABContactDisplay *display, EContact *contact)
+{
+ GtkHTMLStream *html_stream;
+
+ if (display->priv->contact)
+ g_object_unref (display->priv->contact);
+ display->priv->contact = contact;
+ if (display->priv->contact)
+ g_object_ref (display->priv->contact);
+
+ html_stream = gtk_html_begin (display->priv->html);
+ gtk_html_stream_write (html_stream, HTML_HEADER, sizeof (HTML_HEADER) - 1);
+ gtk_html_stream_write (html_stream, "<body>\n", 7);
+
+ if (contact) {
+ char *str, *html;
+ EContactPhoto *photo;
+
+ gtk_html_stream_printf (html_stream,
+ "<table width=\"100%%\" cellpadding=1 cellspacing=0 bgcolor=\"#000000\">"
+ "<tr><td>"
+ "<table width=\"100%%\" cellpadding=0 cellspacing=0 bgcolor=\"#eeeeee\">"
+ "<tr><td>"
+ "<table>"
+ "<tr valign=\"top\"><td>");
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+ if (photo) {
+ int calced_width = MAX_COMPACT_IMAGE_DIMENSION, calced_height = MAX_COMPACT_IMAGE_DIMENSION;
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ GdkPixbuf *pixbuf;
+
+ /* figure out if we need to downscale the
+ image here. we don't scale the pixbuf
+ itself, just insert width/height tags in
+ the html */
+ gdk_pixbuf_loader_write (loader, photo->data, photo->length, NULL);
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ gdk_pixbuf_loader_close (loader, NULL);
+ g_object_unref (loader);
+ if (pixbuf) {
+ int max_dimension = gdk_pixbuf_get_height (pixbuf);
+ if (max_dimension < gdk_pixbuf_get_width (pixbuf))
+ max_dimension = gdk_pixbuf_get_width (pixbuf);
+
+ calced_width = (float)gdk_pixbuf_get_width (pixbuf) / max_dimension * MAX_COMPACT_IMAGE_DIMENSION;
+ calced_height = (float)gdk_pixbuf_get_height (pixbuf) / max_dimension * MAX_COMPACT_IMAGE_DIMENSION;
+
+ calced_width = MIN (calced_width, MAX_COMPACT_IMAGE_DIMENSION);
+ calced_height = MIN (calced_height, MAX_COMPACT_IMAGE_DIMENSION);
+ }
+
+ gdk_pixbuf_unref (pixbuf);
+ gtk_html_stream_printf (html_stream, "<img width=\"%d\" height=\"%d\" src=\"internal-contact-photo:\">",
+ calced_width, calced_height);
+ e_contact_photo_free (photo);
+ }
+
+ gtk_html_stream_printf (html_stream, "</td><td>\n");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<b>%s</b>", html);
+ g_free (html);
+ }
+ else {
+ str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<b>%s</b>", html);
+ g_free (html);
+ }
+ }
+
+ gtk_html_stream_write (html_stream, "<hr>", 4);
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ GList *email_list;
+ GList *l;
+
+ gtk_html_stream_printf (html_stream, "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr valign=\"top\"><td>");
+ gtk_html_stream_printf (html_stream, "<b>%s:</b>&nbsp;<td>", _("List Members"));
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+ for (l = email_list; l; l = l->next) {
+ EABDestination *dest = eab_destination_import (l->data);
+ if (dest) {
+ const char *textrep = eab_destination_get_textrep (dest, TRUE);
+ char *html = e_text_to_html (textrep, 0);
+ gtk_html_stream_printf (html_stream, "%s, ", html);
+ g_free (html);
+ g_object_unref (dest);
+ }
+ }
+ gtk_html_stream_printf (html_stream, "</td></tr></table>");
+ }
+ else {
+ gboolean comma = FALSE;
+ str = e_contact_get_const (contact, E_CONTACT_TITLE);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>", _("Job Title"), str);
+ g_free (html);
+ }
+
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> ", _("Email"));
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "%s", str);
+ g_free (html);
+ comma = TRUE;
+ }
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_2);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "%s%s", comma ? ", " : "", str);
+ g_free (html);
+ comma = TRUE;
+ }
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_3);
+ if (str) {
+ html = e_text_to_html (str, 0);
+ gtk_html_stream_printf (html_stream, "%s%s", comma ? ", " : "", str);
+ g_free (html);
+ }
+ gtk_html_stream_write (html_stream, "<br>", 4);
+
+ str = e_contact_get_const (contact, E_CONTACT_HOMEPAGE_URL);
+ if (str) {
+ html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>",
+ _("Home page"), html);
+ g_free (html);
+ }
+
+ str = e_contact_get_const (contact, E_CONTACT_BLOG_URL);
+ if (str) {
+ html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>",
+ _("Blog"), html);
+ }
+ }
+
+ gtk_html_stream_printf (html_stream, "</td></tr></table></td></tr></table></td></tr></table>\n");
+ }
+
+ gtk_html_stream_write (html_stream, "</body></html>\n", 15);
+ gtk_html_end (display->priv->html, html_stream, GTK_HTML_STREAM_OK);
+}
+
+void
+eab_contact_display_render (EABContactDisplay *display, EContact *contact,
+ EABContactDisplayRenderMode mode)
+{
+ switch (mode) {
+ case EAB_CONTACT_DISPLAY_RENDER_NORMAL:
+ eab_contact_display_render_normal (display, contact);
+ break;
+ case EAB_CONTACT_DISPLAY_RENDER_COMPACT:
+ eab_contact_display_render_compact (display, contact);
+ break;
+ }
+}
+
+GtkWidget*
+eab_contact_display_new (void)
+{
+ EABContactDisplay *display;
+
+ display = g_object_new (EAB_TYPE_CONTACT_DISPLAY, NULL);
+
+ display->priv = g_new0 (EABContactDisplayPrivate, 1);
+
+ display->priv->html = GTK_HTML (gtk_html_new ());
+
+ gtk_html_set_default_content_type (display->priv->html, "text/html; charset=utf-8");
+
+ gtk_html_set_editable (display->priv->html, FALSE);
+
+
+ g_signal_connect (display->priv->html, "url_requested",
+ G_CALLBACK (on_url_requested),
+ display);
+ g_signal_connect (display->priv->html, "link_clicked",
+ G_CALLBACK (on_link_clicked),
+ display);
+#if 0
+ g_signal_connect (display->priv->html, "object_requested",
+ G_CALLBACK (on_object_requested),
+ mail_display);
+ g_signal_connect (display->priv->html, "button_press_event",
+ G_CALLBACK (html_button_press_event), mail_display);
+ g_signal_connect (display->priv->html, "motion_notify_event",
+ G_CALLBACK (html_motion_notify_event), mail_display);
+ g_signal_connect (display->priv->html, "enter_notify_event",
+ G_CALLBACK (html_enter_notify_event), mail_display);
+ g_signal_connect (display->priv->html, "iframe_created",
+ G_CALLBACK (html_iframe_created), mail_display);
+ g_signal_connect (display->priv->html, "on_url",
+ G_CALLBACK (html_on_url), mail_display);
+#endif
+
+ gtk_box_pack_start_defaults (GTK_BOX (display), GTK_WIDGET (display->priv->html));
+ gtk_widget_show (GTK_WIDGET (display->priv->html));
+
+ return GTK_WIDGET (display);
+}
+
+
+static void
+eab_contact_display_init (GObject *object)
+{
+}
+
+static void
+eab_contact_display_class_init (GtkObjectClass *object_class)
+{
+ // object_class->destroy = mail_display_destroy;
+}
+
+GType
+eab_contact_display_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (EABContactDisplayClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) eab_contact_display_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EABContactDisplay),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) eab_contact_display_init,
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "EABContactDisplay", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h
new file mode 100644
index 0000000000..83bad9ae64
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _EAB_CONTACT_DISPLAY_H_
+#define _EAB_CONTACT_DISPLAY_H_
+
+#include <gtk/gtkvbox.h>
+#include <gtkhtml/gtkhtml.h>
+#include <ebook/e-contact.h>
+
+#define EAB_TYPE_CONTACT_DISPLAY (eab_contact_display_get_type ())
+#define EAB_CONTACT_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplay))
+#define EAB_CONTACT_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+#define IS_EAB_CONTACT_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_CONTACT_DISPLAY))
+#define IS_EAB_CONTACT_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_CONTACT_DISPLAY))
+
+typedef struct _EABContactDisplay EABContactDisplay;
+typedef struct _EABContactDisplayPrivate EABContactDisplayPrivate;
+typedef struct _EABContactDisplayClass EABContactDisplayClass;
+
+typedef enum {
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL, /* for use in the preview pane */
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT /* for use with embedded vcards (e.g, the EABVCardControl) */
+} EABContactDisplayRenderMode;
+
+struct _EABContactDisplay {
+ GtkVBox parent;
+
+ EABContactDisplayPrivate *priv;
+};
+
+struct _EABContactDisplayClass {
+ GtkVBoxClass parent_class;
+};
+
+GtkType eab_contact_display_get_type (void);
+GtkWidget * eab_contact_display_new (void);
+
+void eab_contact_display_render (EABContactDisplay *display, EContact *contact,
+ EABContactDisplayRenderMode render_mode);
+
+#endif /* _EAB_CONTACT_DISPLAY_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-util.c b/addressbook/gui/widgets/eab-gui-util.c
index 1ddb6812a2..666bc976f2 100644
--- a/addressbook/gui/widgets/e-addressbook-util.c
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -20,26 +20,34 @@
*/
#include <config.h>
-#include "e-addressbook-util.h"
-#include "ebook/e-destination.h"
-#include <gnome.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
#include <gal/util/e-util.h>
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
+#include "util/eab-destination.h"
+
+#include <gnome.h>
-#include "e-card-merging.h"
#include <shell/evolution-shell-client.h>
-#include <addressbook/backend/ebook/e-book-util.h>
+
+#include "addressbook/gui/contact-editor/e-contact-editor.h"
+#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
void
-e_addressbook_error_dialog (const gchar *msg, EBookStatus status)
+eab_error_dialog (const gchar *msg, EBookStatus status)
{
static char *status_to_string[] = {
N_("Success"),
N_("Unknown error"),
N_("Repository offline"),
N_("Permission denied"),
- N_("Card not found"),
- N_("Card ID already exists"),
+ N_("Contact not found"),
+ N_("Contact ID already exists"),
N_("Protocol not supported"),
N_("Cancelled"),
N_("Authentication Failed"),
@@ -64,7 +72,7 @@ e_addressbook_error_dialog (const gchar *msg, EBookStatus status)
}
gint
-e_addressbook_prompt_save_dialog (GtkWindow *parent)
+eab_prompt_save_dialog (GtkWindow *parent)
{
GtkWidget *dialog;
gint response;
@@ -93,8 +101,8 @@ static void
added_cb (EBook* book, EBookStatus status, const char *id,
gboolean is_list)
{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error adding list") : _("Error adding card"), status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (is_list ? _("Error adding list") : _("Error adding contact"), status);
}
}
@@ -102,9 +110,9 @@ static void
modified_cb (EBook* book, EBookStatus status,
gboolean is_list)
{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error modifying list") : _("Error modifying card"),
- status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (is_list ? _("Error modifying list") : _("Error modifying contact"),
+ status);
}
}
@@ -112,9 +120,9 @@ static void
deleted_cb (EBook* book, EBookStatus status,
gboolean is_list)
{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error removing list") : _("Error removing card"),
- status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (is_list ? _("Error removing list") : _("Error removing contact"),
+ status);
}
}
@@ -125,19 +133,19 @@ editor_closed_cb (GtkObject *editor, gpointer data)
}
EContactEditor *
-e_addressbook_show_contact_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
+eab_show_contact_editor (EBook *book, EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable)
{
EContactEditor *ce;
- ce = e_contact_editor_new (book, card, is_new_card, editable);
+ ce = e_contact_editor_new (book, contact, is_new_contact, editable);
- g_signal_connect (ce, "card_added",
+ g_signal_connect (ce, "contact_added",
G_CALLBACK (added_cb), GINT_TO_POINTER (FALSE));
- g_signal_connect (ce, "card_modified",
+ g_signal_connect (ce, "contact_modified",
G_CALLBACK (modified_cb), GINT_TO_POINTER (FALSE));
- g_signal_connect (ce, "card_deleted",
+ g_signal_connect (ce, "contact_deleted",
G_CALLBACK (deleted_cb), GINT_TO_POINTER (FALSE));
g_signal_connect (ce, "editor_closed",
G_CALLBACK (editor_closed_cb), NULL);
@@ -146,13 +154,13 @@ e_addressbook_show_contact_editor (EBook *book, ECard *card,
}
EContactListEditor *
-e_addressbook_show_contact_list_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
+eab_show_contact_list_editor (EBook *book, EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable)
{
EContactListEditor *ce;
- ce = e_contact_list_editor_new (book, card, is_new_card, editable);
+ ce = e_contact_list_editor_new (book, contact, is_new_contact, editable);
g_signal_connect (ce, "list_added",
G_CALLBACK (added_cb), GINT_TO_POINTER (TRUE));
@@ -169,21 +177,21 @@ e_addressbook_show_contact_list_editor (EBook *book, ECard *card,
}
static void
-view_cards (EBook *book, GList *list, gboolean editable)
+view_contacts (EBook *book, GList *list, gboolean editable)
{
for (; list; list = list->next) {
- ECard *card = list->data;
- if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, editable);
+ EContact *contact = list->data;
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ eab_show_contact_list_editor (book, contact, FALSE, editable);
else
- e_addressbook_show_contact_editor (book, card, FALSE, editable);
+ eab_show_contact_editor (book, contact, FALSE, editable);
}
}
void
-e_addressbook_show_multiple_cards (EBook *book,
- GList *list,
- gboolean editable)
+eab_show_multiple_contacts (EBook *book,
+ GList *list,
+ gboolean editable)
{
if (list) {
int length = g_list_length (list);
@@ -195,40 +203,218 @@ e_addressbook_show_multiple_cards (EBook *book,
0,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
- _("Opening %d cards will open %d new windows as well.\n"
- "Do you really want to display all of these cards?"),
+ _("Opening %d contacts will open %d new windows as well.\n"
+ "Do you really want to display all of these contacts?"),
length,
length);
response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
if (response == GTK_RESPONSE_YES)
- view_cards (book, list, editable);
+ view_contacts (book, list, editable);
} else {
- view_cards (book, list, editable);
+ view_contacts (book, list, editable);
}
}
}
+static gint
+file_exists(GtkFileSelection *filesel, const char *filename)
+{
+ GtkWidget *dialog;
+ gint response;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (filesel),
+ 0,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("%s already exists\nDo you want to overwrite it?"), filename);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ _("Overwrite"), GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ return response;
+}
+
+typedef struct {
+ GtkFileSelection *filesel;
+ char *vcard;
+} SaveAsInfo;
+
+static void
+save_it(GtkWidget *widget, SaveAsInfo *info)
+{
+ gint error = 0;
+ gint response = 0;
+
+ const char *filename = gtk_file_selection_get_filename (info->filesel);
+
+ error = e_write_file (filename, info->vcard, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC);
+
+ if (error == EEXIST) {
+ response = file_exists(info->filesel, filename);
+ switch (response) {
+ case GTK_RESPONSE_ACCEPT : /* Overwrite */
+ e_write_file(filename, info->vcard, O_WRONLY | O_CREAT | O_TRUNC);
+ break;
+ case GTK_RESPONSE_REJECT : /* cancel */
+ return;
+ }
+ } else if (error != 0) {
+ GtkWidget *dialog;
+ char *str;
+
+ str = g_strdup_printf (_("Error saving %s: %s"), filename, strerror(errno));
+ dialog = gtk_message_dialog_new (GTK_WINDOW (info->filesel),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ str);
+ g_free (str);
+
+ gtk_widget_show (dialog);
+
+ return;
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(info->filesel));
+}
+
+static void
+close_it(GtkWidget *widget, SaveAsInfo *info)
+{
+ gtk_widget_destroy (GTK_WIDGET (info->filesel));
+}
-typedef struct CardCopyProcess_ CardCopyProcess;
+static void
+destroy_it(void *data, GObject *where_the_object_was)
+{
+ SaveAsInfo *info = data;
+ g_free (info->vcard);
+ g_free (info);
+}
-typedef void (*CardCopyDone) (CardCopyProcess *process);
+static char *
+make_safe_filename (const char *prefix, char *name)
+{
+ char *safe, *p;
-struct CardCopyProcess_ {
+ if (!name) {
+ /* This is a filename. Translators take note. */
+ name = _("card.vcf");
+ }
+
+ p = strrchr (name, '/');
+ if (p)
+ safe = g_strdup_printf ("%s%s%s", prefix, p, ".vcf");
+ else
+ safe = g_strdup_printf ("%s/%s%s", prefix, name, ".vcf");
+
+ p = strrchr (safe, '/') + 1;
+ if (p)
+ e_filename_make_safe (p);
+
+ return safe;
+}
+
+void
+eab_contact_save (char *title, EContact *contact, GtkWindow *parent_window)
+{
+ GtkFileSelection *filesel;
+ char *file;
+ char *name;
+ SaveAsInfo *info = g_new(SaveAsInfo, 1);
+
+ filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title));
+
+ name = e_contact_get (contact, E_CONTACT_FILE_AS);
+ file = make_safe_filename (g_get_home_dir(), name);
+ gtk_file_selection_set_filename (filesel, file);
+ g_free (file);
+
+ info->filesel = filesel;
+ info->vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+
+ g_signal_connect(filesel->ok_button, "clicked",
+ G_CALLBACK (save_it), info);
+ g_signal_connect(filesel->cancel_button, "clicked",
+ G_CALLBACK (close_it), info);
+ g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
+
+ if (parent_window) {
+ gtk_window_set_transient_for (GTK_WINDOW (filesel),
+ parent_window);
+ gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
+ }
+
+ gtk_widget_show(GTK_WIDGET(filesel));
+}
+
+void
+eab_contact_list_save (char *title, GList *list, GtkWindow *parent_window)
+{
+ GtkFileSelection *filesel;
+ SaveAsInfo *info = g_new(SaveAsInfo, 1);
+
+ filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title));
+
+ /* This is a filename. Translators take note. */
+ if (list && list->data && list->next == NULL) {
+ char *name, *file;
+ name = e_contact_get (E_CONTACT (list->data), E_CONTACT_FILE_AS);
+ if (!name)
+ name = e_contact_get (E_CONTACT (list->data), E_CONTACT_FULL_NAME);
+
+ file = make_safe_filename (g_get_home_dir(), name);
+ gtk_file_selection_set_filename (filesel, file);
+ g_free (file);
+ } else {
+ char *file;
+ file = make_safe_filename (g_get_home_dir(), _("list"));
+ gtk_file_selection_set_filename (filesel, file);
+ g_free (file);
+ }
+
+ info->filesel = filesel;
+ info->vcard = eab_contact_list_to_string (list);
+
+ g_signal_connect(filesel->ok_button, "clicked",
+ G_CALLBACK (save_it), info);
+ g_signal_connect(filesel->cancel_button, "clicked",
+ G_CALLBACK (close_it), info);
+ g_object_weak_ref (G_OBJECT (filesel), destroy_it, info);
+
+ if (parent_window) {
+ gtk_window_set_transient_for (GTK_WINDOW (filesel),
+ parent_window);
+ gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
+ }
+
+ gtk_widget_show(GTK_WIDGET(filesel));
+}
+
+typedef struct ContactCopyProcess_ ContactCopyProcess;
+
+typedef void (*ContactCopyDone) (ContactCopyProcess *process);
+
+struct ContactCopyProcess_ {
int count;
- GList *cards;
+ GList *contacts;
EBook *source;
EBook *destination;
- CardCopyDone done_cb;
+ ContactCopyDone done_cb;
};
static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
+contact_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (_("Error removing contact"), status);
}
}
@@ -236,28 +422,28 @@ static void
do_delete (gpointer data, gpointer user_data)
{
EBook *book = user_data;
- ECard *card = data;
+ EContact *contact = data;
- e_book_remove_card(book, card, card_deleted_cb, NULL);
+ e_book_async_remove_contact(book, contact, contact_deleted_cb, NULL);
}
static void
-delete_cards (CardCopyProcess *process)
+delete_contacts (ContactCopyProcess *process)
{
- g_list_foreach (process->cards,
+ g_list_foreach (process->contacts,
do_delete,
process->source);
}
static void
-process_unref (CardCopyProcess *process)
+process_unref (ContactCopyProcess *process)
{
process->count --;
if (process->count == 0) {
if (process->done_cb) {
process->done_cb (process);
}
- e_free_object_list(process->cards);
+ e_free_object_list(process->contacts);
g_object_unref (process->source);
g_object_unref (process->destination);
g_free (process);
@@ -265,12 +451,12 @@ process_unref (CardCopyProcess *process)
}
static void
-card_added_cb (EBook* book, EBookStatus status, const char *id, gpointer user_data)
+contact_added_cb (EBook* book, EBookStatus status, const char *id, gpointer user_data)
{
- CardCopyProcess *process = user_data;
+ ContactCopyProcess *process = user_data;
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error adding card"), status);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (_("Error adding contact"), status);
} else {
process_unref (process);
}
@@ -280,66 +466,70 @@ static void
do_copy (gpointer data, gpointer user_data)
{
EBook *book;
- ECard *card;
- CardCopyProcess *process;
+ EContact *contact;
+ ContactCopyProcess *process;
process = user_data;
- card = data;
+ contact = data;
book = process->destination;
process->count ++;
- e_book_add_card(book, card, card_added_cb, process);
+ e_book_async_add_contact(book, contact, contact_added_cb, process);
}
static void
-got_book_cb (EBook *book, gpointer closure)
+got_book_cb (EBook *book, EBookStatus status, gpointer closure)
{
- CardCopyProcess *process;
+ ContactCopyProcess *process;
process = closure;
- if (book) {
+ if (status == E_BOOK_ERROR_OK) {
process->destination = book;
g_object_ref (book);
- g_list_foreach (process->cards,
+ g_list_foreach (process->contacts,
do_copy,
process);
}
process_unref (process);
}
-extern EvolutionShellClient *global_shell_client;
-
void
-e_addressbook_transfer_cards (EBook *source, GList *cards /* adopted */, gboolean delete_from_source, GtkWindow *parent_window)
+eab_transfer_contacts (EBook *source, GList *contacts /* adopted */, gboolean delete_from_source, GtkWindow *parent_window)
{
+ EBook *dest;
const char *allowed_types[] = { "contacts/*", NULL };
GNOME_Evolution_Folder *folder;
static char *last_uri = NULL;
- CardCopyProcess *process;
+ ContactCopyProcess *process;
char *desc;
- if (cards == NULL)
+ if (contacts == NULL)
return;
if (last_uri == NULL)
last_uri = g_strdup ("");
- if (cards->next == NULL) {
+ if (contacts->next == NULL) {
if (delete_from_source)
- desc = _("Move card to");
+ desc = _("Move contact to");
else
- desc = _("Copy card to");
+ desc = _("Copy contact to");
} else {
if (delete_from_source)
- desc = _("Move cards to");
+ desc = _("Move contacts to");
else
- desc = _("Copy cards to");
+ desc = _("Copy contacts to");
}
+#if 0 /* EPFIXME */
evolution_shell_client_user_select_folder (global_shell_client,
parent_window,
desc, last_uri, allowed_types,
&folder);
+#else
+ folder = NULL;
+#endif
+
if (!folder)
return;
@@ -348,19 +538,20 @@ e_addressbook_transfer_cards (EBook *source, GList *cards /* adopted */, gboolea
last_uri = g_strdup (folder->evolutionUri);
}
- process = g_new (CardCopyProcess, 1);
+ process = g_new (ContactCopyProcess, 1);
process->count = 1;
process->source = source;
g_object_ref (source);
- process->cards = cards;
+ process->contacts = contacts;
process->destination = NULL;
if (delete_from_source)
- process->done_cb = delete_cards;
+ process->done_cb = delete_contacts;
else
process->done_cb = NULL;
- e_book_use_address_book_by_uri (folder->physicalUri, got_book_cb, process);
+ dest = e_book_new ();
+ e_book_async_load_uri (dest, folder->physicalUri, got_book_cb, process);
CORBA_free (folder);
}
@@ -370,19 +561,20 @@ e_addressbook_transfer_cards (EBook *source, GList *cards /* adopted */, gboolea
#define COMPOSER_OAFID "OAFIID:GNOME_Evolution_Mail_Composer"
void
-e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
+eab_send_contact_list (GList *contacts, EABDisposition disposition)
{
+#if notyet
GNOME_Evolution_Composer composer_server;
CORBA_Environment ev;
- if (cards == NULL)
+ if (contacts == NULL)
return;
CORBA_exception_init (&ev);
composer_server = bonobo_activation_activate_from_id (COMPOSER_OAFID, 0, NULL, &ev);
- if (disposition == E_ADDRESSBOOK_DISPOSITION_AS_TO) {
+ if (disposition == EAB_DISPOSITION_AS_TO) {
GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list;
CORBA_char *subject;
int to_i, bcc_i;
@@ -390,9 +582,9 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
gint to_length = 0, bcc_length = 0;
/* Figure out how many addresses of each kind we have. */
- for (iter = cards; iter != NULL; iter = g_list_next (iter)) {
- ECard *card = E_CARD (iter->data);
- if (e_card_evolution_list (card)) {
+ for (iter = contacts; iter != NULL; iter = g_list_next (iter)) {
+ EContact *contact = E_CONTACT (iter->data);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
gint len = card->email ? e_list_length (card->email) : 0;
if (e_card_evolution_list_show_addresses (card))
to_length += len;
@@ -453,11 +645,11 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
if (e_iterator_is_valid (iterator)) {
if (is_list) {
- /* We need to decode the list entries, which are XMLified EDestinations. */
- EDestination *dest = e_destination_import (e_iterator_get (iterator));
+ /* We need to decode the list entries, which are XMLified EABDestinations. */
+ EABDestination *dest = eab_destination_import (e_iterator_get (iterator));
if (dest != NULL) {
- name = g_strdup (e_destination_get_name (dest));
- addr = g_strdup (e_destination_get_email (dest));
+ name = g_strdup (eab_destination_get_name (dest));
+ addr = g_strdup (eab_destination_get_email (dest));
free_name_addr = TRUE;
g_object_unref (dest);
}
@@ -502,7 +694,7 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
CORBA_free (cc_list);
CORBA_free (bcc_list);
CORBA_free (subject);
- } else if (disposition == E_ADDRESSBOOK_DISPOSITION_AS_ATTACHMENT) {
+ } else if (disposition == EAB_DISPOSITION_AS_ATTACHMENT) {
CORBA_char *content_type, *filename, *description;
GNOME_Evolution_Composer_AttachmentData *attach_data;
CORBA_boolean show_inline;
@@ -526,16 +718,15 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
tempstr = g_strdup_printf (_("VCard for %s"), file_as);
description = CORBA_string_dup (tempstr);
g_free (tempstr);
- g_free (file_as);
}
show_inline = FALSE;
- tempstr = e_card_list_get_vcard (cards);
+ tempstr = eab_contact_list_to_string (cards);
attach_data = GNOME_Evolution_Composer_AttachmentData__alloc();
attach_data->_maximum = attach_data->_length = strlen (tempstr);
attach_data->_buffer = CORBA_sequence_CORBA_char_allocbuf (attach_data->_length);
- memcpy(attach_data->_buffer, tempstr, attach_data->_length);
+ strcpy (attach_data->_buffer, tempstr);
g_free (tempstr);
GNOME_Evolution_Composer_attachData (composer_server,
@@ -573,17 +764,15 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
g_object_get(card,
"file_as", &tempstr2,
NULL);
- if (!tempstr2 || !*tempstr2) {
- g_free (tempstr2);
+ if (!tempstr2 || !*tempstr2)
g_object_get(card,
"full_name", &tempstr2,
NULL);
- } if (!tempstr2 || !*tempstr2) {
- g_free (tempstr2);
+ if (!tempstr2 || !*tempstr2)
g_object_get(card,
"org", &tempstr2,
NULL);
- } if (!tempstr2 || !*tempstr2) {
+ if (!tempstr2 || !*tempstr2) {
EList *list;
EIterator *iterator;
g_object_get(card,
@@ -594,7 +783,6 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
tempstr2 = e_iterator_get (iterator);
}
g_object_unref (iterator);
- g_object_unref (list);
}
if (!tempstr2 || !*tempstr2)
@@ -602,7 +790,6 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
else
tempstr = g_strdup_printf ("Contact information for %s", tempstr2);
subject = CORBA_string_dup (tempstr);
- g_free (tempstr2);
g_free (tempstr);
}
@@ -623,14 +810,14 @@ e_addressbook_send_card_list (GList *cards, EAddressbookDisposition disposition)
}
CORBA_exception_free (&ev);
+#endif
}
void
-e_addressbook_send_card (ECard *card, EAddressbookDisposition disposition)
+eab_send_contact (EContact *contact, EABDisposition disposition)
{
GList *list;
- list = g_list_prepend (NULL, card);
- e_addressbook_send_card_list (list, disposition);
+ list = g_list_prepend (NULL, contact);
+ eab_send_contact_list (list, disposition);
g_list_free (list);
}
-
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
new file mode 100644
index 0000000000..71a80bc7a6
--- /dev/null
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eab-gui-util.h
+ * Copyright (C) 2001-2003 Ximian, Inc.
+ * Author: Chris Toshok <toshok@ximian.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_ADDRESSBOOK_UTIL_H__
+#define __E_ADDRESSBOOK_UTIL_H__
+
+#include <gtk/gtkwindow.h>
+#include "addressbook/backend/ebook/e-book.h"
+#include "addressbook/gui/contact-editor/e-contact-editor.h"
+#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
+
+G_BEGIN_DECLS
+
+void eab_error_dialog (const gchar *msg,
+ EBookStatus status);
+gint eab_prompt_save_dialog (GtkWindow *parent);
+
+EContactEditor *eab_show_contact_editor (EBook *book,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable);
+EContactListEditor *eab_show_contact_list_editor (EBook *book,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable);
+void eab_show_multiple_contacts (EBook *book,
+ GList *list,
+ gboolean editable);
+void eab_transfer_contacts (EBook *source,
+ GList *contacts, /* adopted */
+ gboolean delete_from_source,
+ GtkWindow *parent_window);
+
+void eab_contact_save (char *title,
+ EContact *contact,
+ GtkWindow *parent_window);
+
+void eab_contact_list_save (char *title,
+ GList *list,
+ GtkWindow *parent_window);
+
+typedef enum {
+ EAB_DISPOSITION_AS_ATTACHMENT,
+ EAB_DISPOSITION_AS_TO,
+} EABDisposition;
+
+void eab_send_contact (EContact *contact,
+ EABDisposition disposition);
+void eab_send_contact_list (GList *contacts,
+ EABDisposition disposition);
+
+G_END_DECLS
+
+#endif /* __E_ADDRESSBOOK_UTIL_H__ */
diff --git a/addressbook/gui/widgets/e-addressbook-marshal.list b/addressbook/gui/widgets/eab-marshal.list
index 2b34707dbb..2b34707dbb 100644
--- a/addressbook/gui/widgets/e-addressbook-marshal.list
+++ b/addressbook/gui/widgets/eab-marshal.list
diff --git a/addressbook/gui/component/e-address-popup.c b/addressbook/gui/widgets/eab-popup-control.c
index 9d87fd0fb3..e2d0299d6e 100644
--- a/addressbook/gui/component/e-address-popup.c
+++ b/addressbook/gui/widgets/eab-popup-control.c
@@ -1,11 +1,12 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-address-popup.c
+ * eab-popup-control.c
*
- * Copyright (C) 2001 Ximian, Inc.
+ * Copyright (C) 2001-2003, Ximian, Inc.
*
- * Developed by Jon Trowbridge <trow@ximian.com>
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
*/
/*
@@ -31,19 +32,22 @@
#include <config.h>
#include <string.h>
#include "addressbook.h"
-#include "e-address-popup.h"
+#include "eab-popup-control.h"
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-property-bag.h>
#include <bonobo/bonobo-generic-factory.h>
#include <gal/widgets/e-popup-menu.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
+#include <addressbook/backend/ebook/e-book-async.h>
+#include <addressbook/util/eab-book-util.h>
#include <addressbook/gui/contact-editor/e-contact-editor.h>
#include <addressbook/gui/contact-editor/e-contact-quick-add.h>
-#include <addressbook/gui/widgets/e-minicard-widget.h>
-#include <addressbook/gui/widgets/e-addressbook-util.h>
+#include <addressbook/gui/widgets/eab-contact-display.h>
+#include <addressbook/gui/widgets/eab-gui-util.h>
#include "e-util/e-gui-utils.h"
+static void eab_popup_control_set_name (EABPopupControl *pop, const gchar *name);
+static void eab_popup_control_set_email (EABPopupControl *pop, const gchar *email);
+
/*
* Some general scaffolding for our widgets. Think of this as a really, really
* lame implementation of a wizard (...which is still somewhat more general that
@@ -178,7 +182,7 @@ mini_wizard_new (void)
/*
* This is the code for the UI thingie that lets you manipulate the e-mail
* addresses (and *only* the e-mail addresses) associated with an existing
- * card.
+ * contact.
*/
#define EMPTY_ENTRY N_("(none)")
@@ -225,20 +229,18 @@ menu_activate_cb (GtkWidget *w, gpointer closure)
}
static void
-email_menu_add_option (EMailMenu *menu, const gchar *addr)
+email_menu_add_option (EMailMenu *menu, char *addr)
{
GtkWidget *menu_item;
- gchar *addr_cpy;
g_return_if_fail (menu != NULL);
if (addr == NULL)
return;
- addr_cpy = g_strdup (addr);
- menu->options = g_list_append (menu->options, addr_cpy);
+ menu->options = g_list_append (menu->options, addr);
menu_item = gtk_menu_item_new_with_label (addr);
- g_object_set_data (G_OBJECT (menu_item), "addr", addr_cpy);
+ g_object_set_data (G_OBJECT (menu_item), "addr", addr);
gtk_widget_show_all (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (gtk_option_menu_get_menu (GTK_OPTION_MENU (menu->option_menu))), menu_item);
@@ -249,23 +251,17 @@ email_menu_add_option (EMailMenu *menu, const gchar *addr)
}
static void
-email_menu_add_options_from_card (EMailMenu *menu, ECard *card, const gchar *extra_addr)
+email_menu_add_options_from_contact (EMailMenu *menu, EContact *contact, const gchar *extra_addr)
{
- ECardSimple *simple;
-
- g_return_if_fail (card && E_IS_CARD (card));
-
- simple = e_card_simple_new (card);
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
/* If any of these three e-mail fields are NULL, email_menu_add_option will just
return without doing anything. */
- email_menu_add_option (menu, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL));
- email_menu_add_option (menu, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2));
- email_menu_add_option (menu, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3));
- email_menu_add_option (menu, extra_addr);
+ email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_1));
+ email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_2));
+ email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_3));
+ email_menu_add_option (menu, g_strdup (extra_addr));
email_menu_add_option (menu, EMPTY_ENTRY);
-
- g_object_unref (simple);
}
static void
@@ -325,7 +321,7 @@ email_menu_unset_option (EMailMenu *menu, const gchar *addr)
typedef struct _EMailTable EMailTable;
struct _EMailTable {
GtkWidget *table;
- ECard *card;
+ EContact *contact;
EMailMenu *primary;
EMailMenu *email2;
EMailMenu *email3;
@@ -339,7 +335,7 @@ email_table_cleanup_cb (gpointer closure)
if (et == NULL)
return;
- g_object_unref (et->card);
+ g_object_unref (et->contact);
email_menu_free (et->primary);
email_menu_free (et->email2);
email_menu_free (et->email3);
@@ -348,74 +344,49 @@ email_table_cleanup_cb (gpointer closure)
}
static void
-email_table_from_card (EMailTable *et)
+email_table_from_contact (EMailTable *et)
{
- ECardSimple *simple;
-
g_return_if_fail (et != NULL);
- simple = e_card_simple_new (et->card);
- email_menu_set_option (et->primary, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL));
- email_menu_set_option (et->email2, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2));
- email_menu_set_option (et->email3, e_card_simple_get_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3));
- g_object_unref (simple);
+ email_menu_set_option (et->primary, e_contact_get_const (et->contact, E_CONTACT_EMAIL_1));
+ email_menu_set_option (et->email2, e_contact_get_const (et->contact, E_CONTACT_EMAIL_2));
+ email_menu_set_option (et->email3, e_contact_get_const (et->contact, E_CONTACT_EMAIL_3));
}
static void
-email_table_to_card (EMailTable *et)
+email_table_to_contact (EMailTable *et)
{
- ECardSimple *simple;
gchar *curr;
g_return_if_fail (et != NULL);
- simple = e_card_simple_new (et->card);
-
curr = et->primary->current_selection;
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
curr = NULL;
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL, curr);
+ e_contact_set (et->contact, E_CONTACT_EMAIL_1, curr);
curr = et->email2->current_selection;
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
curr = NULL;
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, curr);
+ e_contact_set (et->contact, E_CONTACT_EMAIL_2, curr);
curr = et->email3->current_selection;
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
curr = NULL;
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, curr);
-
- e_card_simple_sync_card (simple);
- g_object_unref (simple);
+ e_contact_set (et->contact, E_CONTACT_EMAIL_3, curr);
}
static void
-email_table_save_card_cb (EBook *book, EBookStatus status, gpointer closure)
+email_table_save_contact_cb (EBook *book, EBookStatus status, gpointer closure)
{
- ECard *card = E_CARD (closure);
+ EContact *contact = E_CONTACT (closure);
- if (status == E_BOOK_STATUS_SUCCESS) {
- e_book_commit_card (book, card, NULL, NULL);
+ if (status == E_BOOK_ERROR_OK) {
+ e_book_async_commit_contact (book, contact, NULL, NULL);
}
if (book)
g_object_unref (book);
- g_object_unref (card);
-}
-
-/*
- * We have to do this in an idle function because of what might be a
- * re-entrancy problems with EBook.
- */
-static gint
-add_card_idle_cb (gpointer closure)
-{
- EBook *book;
-
- book = e_book_new ();
- addressbook_load_default_book (book, email_table_save_card_cb, closure);
-
- return 0;
+ g_object_unref (contact);
}
static void
@@ -423,16 +394,17 @@ email_table_ok_cb (MiniWizard *wiz, gpointer closure)
{
EMailTable *et = (EMailTable *) closure;
- email_table_to_card (et);
+ email_table_to_contact (et);
+
+ g_object_ref (et->contact);
- g_object_ref (et->card);
- gtk_idle_add (add_card_idle_cb, et->card);
+ addressbook_load_default_book (email_table_save_contact_cb, et->contact);
mini_wizard_destroy (wiz);
}
static void
-email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
+email_table_init (MiniWizard *wiz, EContact *contact, const gchar *extra_address)
{
EMailTable *et;
@@ -441,12 +413,12 @@ email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
GtkAttachOptions label_x_opts, label_y_opts;
GtkAttachOptions menu_x_opts, menu_y_opts;
- g_return_if_fail (card && E_IS_CARD (card));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
et = g_new (EMailTable, 1);
- et->card = card;
- g_object_ref (et->card);
+ et->contact = contact;
+ g_object_ref (et->contact);
et->table = gtk_table_new (4, 2, FALSE);
@@ -454,11 +426,11 @@ email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
et->email2 = email_menu_new ();
et->email3 = email_menu_new ();
- email_menu_add_options_from_card (et->primary, et->card, extra_address);
- email_menu_add_options_from_card (et->email2, et->card, extra_address);
- email_menu_add_options_from_card (et->email3, et->card, extra_address);
+ email_menu_add_options_from_contact (et->primary, et->contact, extra_address);
+ email_menu_add_options_from_contact (et->email2, et->contact, extra_address);
+ email_menu_add_options_from_contact (et->email3, et->contact, extra_address);
- email_table_from_card (et);
+ email_table_from_contact (et);
label_x_opts = GTK_FILL;
label_y_opts = GTK_FILL;
@@ -467,7 +439,7 @@ email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
xpad = 3;
ypad = 3;
- name_str = e_card_name_to_string (et->card->name);
+ name_str = e_contact_get (et->contact, E_CONTACT_FULL_NAME);
gtk_table_attach (GTK_TABLE (et->table),
gtk_label_new (name_str),
0, 2, 0, 1,
@@ -516,32 +488,32 @@ email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
}
/*
- * This code is for the little UI thing that lets you pick from a set of cards
+ * This code is for the little UI thing that lets you pick from a set of contacts
* and decide which one you want to add the e-mail address to.
*/
-typedef struct _CardPicker CardPicker;
-struct _CardPicker {
+typedef struct _ContactPicker ContactPicker;
+struct _ContactPicker {
GtkWidget *body;
GtkWidget *list;
GtkListStore *model;
- GList *cards;
+ GList *contacts;
gchar *new_name;
gchar *new_email;
- ECard *current_card;
+ EContact *current_contact;
};
enum {
COLUMN_ACTION,
- COLUMN_CARD
+ COLUMN_CONTACT
};
static void
-card_picker_selection_changed (GtkTreeSelection *selection, gpointer closure)
+contact_picker_selection_changed (GtkTreeSelection *selection, gpointer closure)
{
MiniWizard *wiz = (MiniWizard *) closure;
- CardPicker *pick = (CardPicker *) wiz->closure;
+ ContactPicker *pick = (ContactPicker *) wiz->closure;
gboolean selected;
GtkTreeIter iter;
@@ -551,34 +523,34 @@ card_picker_selection_changed (GtkTreeSelection *selection, gpointer closure)
if (selected) {
gtk_tree_model_get (GTK_TREE_MODEL (pick->model), &iter,
- COLUMN_CARD, &pick->current_card,
+ COLUMN_CONTACT, &pick->current_contact,
-1);
}
else {
- pick->current_card = NULL;
+ pick->current_contact = NULL;
}
}
static void
-card_picker_ok_cb (MiniWizard *wiz, gpointer closure)
+contact_picker_ok_cb (MiniWizard *wiz, gpointer closure)
{
- CardPicker *pick = (CardPicker *) closure;
+ ContactPicker *pick = (ContactPicker *) closure;
- if (pick->current_card == NULL) {
+ if (pick->current_contact == NULL) {
e_contact_quick_add (pick->new_name, pick->new_email, NULL, NULL);
mini_wizard_destroy (wiz);
} else {
- email_table_init (wiz, pick->current_card, pick->new_email);
+ email_table_init (wiz, pick->current_contact, pick->new_email);
}
}
static void
-card_picker_cleanup_cb (gpointer closure)
+contact_picker_cleanup_cb (gpointer closure)
{
- CardPicker *pick = (CardPicker *) closure;
+ ContactPicker *pick = (ContactPicker *) closure;
- g_list_foreach (pick->cards, (GFunc) g_object_unref, NULL);
- g_list_free (pick->cards);
+ g_list_foreach (pick->contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (pick->contacts);
g_free (pick->new_name);
g_free (pick->new_email);
@@ -592,14 +564,14 @@ free_str (gpointer data,
}
static void
-card_picker_init (MiniWizard *wiz, const GList *cards, const gchar *new_name, const gchar *new_email)
+contact_picker_init (MiniWizard *wiz, const GList *contacts, const gchar *new_name, const gchar *new_email)
{
- CardPicker *pick;
+ ContactPicker *pick;
gchar *str;
GtkWidget *w;
GtkTreeIter iter;
- pick = g_new (CardPicker, 1);
+ pick = g_new (ContactPicker, 1);
pick->body = gtk_vbox_new (FALSE, 2);
@@ -623,44 +595,44 @@ card_picker_init (MiniWizard *wiz, const GList *cards, const gchar *new_name, co
gtk_list_store_append (pick->model, &iter);
gtk_list_store_set (pick->model, &iter,
COLUMN_ACTION, str,
- COLUMN_CARD, NULL,
+ COLUMN_CONTACT, NULL,
-1);
g_object_weak_ref (G_OBJECT (pick->model), free_str, str);
- pick->cards = NULL;
- while (cards) {
- ECard *card = (ECard *) cards->data;
- gchar *name_str = e_card_name_to_string (card->name);
+ pick->contacts = NULL;
+ while (contacts) {
+ EContact *contact = (EContact *) contacts->data;
+ gchar *name_str = e_contact_get (contact, E_CONTACT_FULL_NAME);
- pick->cards = g_list_append (pick->cards, card);
- g_object_ref (card);
+ pick->contacts = g_list_append (pick->contacts, contact);
+ g_object_ref (contact);
str = g_strdup_printf (_("Add address to existing contact \"%s\""), name_str);
gtk_list_store_append (pick->model, &iter);
gtk_list_store_set (pick->model, &iter,
COLUMN_ACTION, str,
- COLUMN_CARD, card,
+ COLUMN_CONTACT, contact,
-1);
g_free (name_str);
g_object_weak_ref (G_OBJECT (pick->model), free_str, str);
- cards = g_list_next (cards);
+ contacts = g_list_next (contacts);
}
pick->new_name = g_strdup (new_name);
pick->new_email = g_strdup (new_email);
- pick->current_card = NULL;
+ pick->current_contact = NULL;
gtk_widget_set_sensitive (wiz->ok_button, FALSE);
/* Connect some signals & callbacks */
- wiz->ok_cb = card_picker_ok_cb;
- wiz->cleanup_cb = card_picker_cleanup_cb;
+ wiz->ok_cb = contact_picker_ok_cb;
+ wiz->cleanup_cb = contact_picker_cleanup_cb;
g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (pick->list)),
- "changed", G_CALLBACK (card_picker_selection_changed),
+ "changed", G_CALLBACK (contact_picker_selection_changed),
wiz);
/* Build our widget */
@@ -681,7 +653,7 @@ card_picker_init (MiniWizard *wiz, const GList *cards, const gchar *new_name, co
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
/*
- * The code for the actual EAddressPopup widget begins here.
+ * The code for the actual EABPopupControl widget begins here.
*/
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
@@ -689,41 +661,43 @@ card_picker_init (MiniWizard *wiz, const GList *cards, const gchar *new_name, co
static GtkObjectClass *parent_class;
-static void e_address_popup_dispose (GObject *);
-static void e_address_popup_query (EAddressPopup *);
+static void eab_popup_control_dispose (GObject *);
+static void eab_popup_control_query (EABPopupControl *);
static void
-e_address_popup_class_init (EAddressPopupClass *klass)
+eab_popup_control_class_init (EABPopupControlClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
- object_class->dispose = e_address_popup_dispose;
+ object_class->dispose = eab_popup_control_dispose;
}
static void
-e_address_popup_init (EAddressPopup *pop)
+eab_popup_control_init (EABPopupControl *pop)
{
pop->transitory = TRUE;
}
static void
-e_address_popup_cleanup (EAddressPopup *pop)
+eab_popup_control_cleanup (EABPopupControl *pop)
{
- if (pop->card) {
- g_object_unref (pop->card);
- pop->card = NULL;
+ if (pop->contact) {
+ g_object_unref (pop->contact);
+ pop->contact = NULL;
}
if (pop->scheduled_refresh) {
- gtk_timeout_remove (pop->scheduled_refresh);
+ g_source_remove (pop->scheduled_refresh);
pop->scheduled_refresh = 0;
}
if (pop->query_tag) {
+#if notyet
e_book_simple_query_cancel (pop->book, pop->query_tag);
+#endif
pop->query_tag = 0;
}
@@ -740,42 +714,42 @@ e_address_popup_cleanup (EAddressPopup *pop)
}
static void
-e_address_popup_dispose (GObject *obj)
+eab_popup_control_dispose (GObject *obj)
{
- EAddressPopup *pop = E_ADDRESS_POPUP (obj);
+ EABPopupControl *pop = EAB_POPUP_CONTROL (obj);
- e_address_popup_cleanup (pop);
+ eab_popup_control_cleanup (pop);
if (G_OBJECT_CLASS (parent_class)->dispose)
G_OBJECT_CLASS (parent_class)->dispose (obj);
}
GType
-e_address_popup_get_type (void)
+eab_popup_control_get_type (void)
{
static GType pop_type = 0;
if (!pop_type) {
static const GTypeInfo pop_info = {
- sizeof (EAddressPopupClass),
+ sizeof (EABPopupControlClass),
NULL, /* base_init */
NULL, /* base_finalize */
- (GClassInitFunc) e_address_popup_class_init,
+ (GClassInitFunc) eab_popup_control_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (EAddressPopup),
+ sizeof (EABPopupControl),
0, /* n_preallocs */
- (GInstanceInitFunc) e_address_popup_init,
+ (GInstanceInitFunc) eab_popup_control_init,
};
- pop_type = g_type_register_static (gtk_event_box_get_type (), "EAddressPopup", &pop_info, 0);
+ pop_type = g_type_register_static (gtk_event_box_get_type (), "EABPopupControl", &pop_info, 0);
}
return pop_type;
}
static void
-e_address_popup_refresh_names (EAddressPopup *pop)
+eab_popup_control_refresh_names (EABPopupControl *pop)
{
if (pop->name_widget) {
if (pop->name && *pop->name) {
@@ -795,33 +769,33 @@ e_address_popup_refresh_names (EAddressPopup *pop)
}
}
- e_address_popup_query (pop);
+ eab_popup_control_query (pop);
}
static gint
refresh_timeout_cb (gpointer ptr)
{
- EAddressPopup *pop = E_ADDRESS_POPUP (ptr);
- e_address_popup_refresh_names (pop);
+ EABPopupControl *pop = EAB_POPUP_CONTROL (ptr);
+ eab_popup_control_refresh_names (pop);
pop->scheduled_refresh = 0;
return 0;
}
static void
-e_address_popup_schedule_refresh (EAddressPopup *pop)
+eab_popup_control_schedule_refresh (EABPopupControl *pop)
{
if (pop->scheduled_refresh == 0)
- pop->scheduled_refresh = gtk_timeout_add (20, refresh_timeout_cb, pop);
+ pop->scheduled_refresh = g_timeout_add (20, refresh_timeout_cb, pop);
}
/* If we are handed something of the form "Foo <bar@bar.com>",
do the right thing. */
static gboolean
-e_address_popup_set_free_form (EAddressPopup *pop, const gchar *txt)
+eab_popup_control_set_free_form (EABPopupControl *pop, const gchar *txt)
{
gchar *lt, *gt = NULL;
- g_return_val_if_fail (pop && E_IS_ADDRESS_POPUP (pop), FALSE);
+ g_return_val_if_fail (pop && EAB_IS_POPUP_CONTROL (pop), FALSE);
if (txt == NULL)
return FALSE;
@@ -833,11 +807,8 @@ e_address_popup_set_free_form (EAddressPopup *pop, const gchar *txt)
if (lt && gt && lt+1 < gt) {
gchar *name = g_strndup (txt, lt-txt);
gchar *email = g_strndup (lt+1, gt-lt-1);
- e_address_popup_set_name (pop, name);
- e_address_popup_set_email (pop, email);
-
- g_free (name);
- g_free (email);
+ eab_popup_control_set_name (pop, name);
+ eab_popup_control_set_email (pop, email);
return TRUE;
}
@@ -845,49 +816,49 @@ e_address_popup_set_free_form (EAddressPopup *pop, const gchar *txt)
return FALSE;
}
-void
-e_address_popup_set_name (EAddressPopup *pop, const gchar *name)
+static void
+eab_popup_control_set_name (EABPopupControl *pop, const gchar *name)
{
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
/* We only allow the name to be set once. */
if (pop->name)
return;
- if (!e_address_popup_set_free_form (pop, name)) {
+ if (!eab_popup_control_set_free_form (pop, name)) {
pop->name = g_strdup (name);
if (pop->name)
g_strstrip (pop->name);
}
- e_address_popup_schedule_refresh (pop);
+ eab_popup_control_schedule_refresh (pop);
}
-void
-e_address_popup_set_email (EAddressPopup *pop, const gchar *email)
+static void
+eab_popup_control_set_email (EABPopupControl *pop, const gchar *email)
{
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
/* We only allow the e-mail to be set once. */
if (pop->email)
return;
- if (!e_address_popup_set_free_form (pop, email)) {
+ if (!eab_popup_control_set_free_form (pop, email)) {
pop->email = g_strdup (email);
if (pop->email)
g_strstrip (pop->email);
}
- e_address_popup_schedule_refresh (pop);
+ eab_popup_control_schedule_refresh (pop);
}
void
-e_address_popup_construct (EAddressPopup *pop)
+eab_popup_control_construct (EABPopupControl *pop)
{
GtkWidget *vbox, *name_holder;
GdkColor color = { 0x0, 0xffff, 0xffff, 0xffff };
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
pop->main_vbox = gtk_vbox_new (FALSE, 0);
@@ -918,9 +889,9 @@ e_address_popup_construct (EAddressPopup *pop)
gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->query_msg, TRUE, TRUE, 0);
gtk_widget_show (pop->query_msg);
- /* Build Minicard View */
- pop->minicard_view = e_minicard_widget_new ();
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->minicard_view, TRUE, TRUE, 0);
+ /* Build ContactDisplay */
+ pop->contact_display = eab_contact_display_new ();
+ gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->contact_display, TRUE, TRUE, 0);
/* Final assembly */
@@ -932,16 +903,16 @@ e_address_popup_construct (EAddressPopup *pop)
gtk_container_set_border_width (GTK_CONTAINER (pop), 2);
}
-GtkWidget *
-e_address_popup_new (void)
+static GtkWidget *
+eab_popup_new (void)
{
- EAddressPopup *pop = g_object_new (E_TYPE_ADDRESS_POPUP, NULL);
- e_address_popup_construct (pop);
+ EABPopupControl *pop = g_object_new (EAB_TYPE_POPUP_CONTROL, NULL);
+ eab_popup_control_construct (pop);
return GTK_WIDGET (pop);
}
static void
-emit_event (EAddressPopup *pop, const char *event)
+emit_event (EABPopupControl *pop, const char *event)
{
if (pop->es) {
BonoboArg *arg;
@@ -960,10 +931,10 @@ emit_event (EAddressPopup *pop, const char *event)
static void
contact_editor_cb (EBook *book, EBookStatus status, gpointer closure)
{
- if (status == E_BOOK_STATUS_SUCCESS) {
- EAddressPopup *pop = E_ADDRESS_POPUP (closure);
- EContactEditor *ce = e_addressbook_show_contact_editor (book, pop->card, FALSE, TRUE);
- e_address_popup_cleanup (pop);
+ if (status == E_BOOK_ERROR_OK) {
+ EABPopupControl *pop = EAB_POPUP_CONTROL (closure);
+ EContactEditor *ce = eab_show_contact_editor (book, pop->contact, FALSE, TRUE);
+ eab_popup_control_cleanup (pop);
emit_event (pop, "Destroy");
e_contact_editor_raise (ce);
}
@@ -973,29 +944,29 @@ contact_editor_cb (EBook *book, EBookStatus status, gpointer closure)
}
static void
-edit_contact_info_cb (GtkWidget *button, EAddressPopup *pop)
+edit_contact_info_cb (GtkWidget *button, EABPopupControl *pop)
{
- EBook *book;
emit_event (pop, "Hide");
- book = e_book_new ();
- addressbook_load_default_book (book, contact_editor_cb, pop);
+ addressbook_load_default_book (contact_editor_cb, pop);
}
static void
-e_address_popup_cardify (EAddressPopup *pop, ECard *card)
+eab_popup_control_display_contact (EABPopupControl *pop, EContact *contact)
{
GtkWidget *b;
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
- g_return_if_fail (card && E_IS_CARD (card));
- g_return_if_fail (pop->card == NULL);
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
+ g_return_if_fail (pop->contact == NULL);
- pop->card = card;
- g_object_ref (pop->card);
+ pop->contact = contact;
+ g_object_ref (pop->contact);
- e_minicard_widget_set_card (E_MINICARD_WIDGET (pop->minicard_view), card);
- gtk_widget_show (pop->minicard_view);
+ eab_contact_display_render (EAB_CONTACT_DISPLAY (pop->contact_display),
+ contact,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ gtk_widget_show (pop->contact_display);
gtk_widget_hide (pop->generic_view);
b = gtk_button_new_with_label (_("Edit Contact Info"));
@@ -1008,7 +979,7 @@ e_address_popup_cardify (EAddressPopup *pop, ECard *card)
}
static void
-add_contacts_cb (GtkWidget *button, EAddressPopup *pop)
+add_contacts_cb (GtkWidget *button, EABPopupControl *pop)
{
if (pop->email && *pop->email) {
if (pop->name && *pop->name)
@@ -1017,16 +988,16 @@ add_contacts_cb (GtkWidget *button, EAddressPopup *pop)
e_contact_quick_add_free_form (pop->email, NULL, NULL);
}
- e_address_popup_cleanup (pop);
+ eab_popup_control_cleanup (pop);
emit_event (pop, "Destroy");
}
static void
-e_address_popup_no_matches (EAddressPopup *pop)
+eab_popup_control_no_matches (EABPopupControl *pop)
{
GtkWidget *b;
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
b = e_button_new_with_stock_icon (_("Add to Contacts"), "gtk-add");
@@ -1045,7 +1016,7 @@ wizard_destroy_cb (MiniWizard *wiz, gpointer closure)
}
static void
-e_address_popup_ambiguous_email_add (EAddressPopup *pop, const GList *cards)
+eab_popup_control_ambiguous_email_add (EABPopupControl *pop, const GList *contacts)
{
MiniWizard *wiz = mini_wizard_new ();
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -1056,9 +1027,9 @@ e_address_popup_ambiguous_email_add (EAddressPopup *pop, const GList *cards)
gtk_window_set_title (GTK_WINDOW (win), _("Merge E-Mail Address"));
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
- card_picker_init (wiz, cards, pop->name, pop->email);
+ contact_picker_init (wiz, contacts, pop->name, pop->email);
- e_address_popup_cleanup (pop);
+ eab_popup_control_cleanup (pop);
emit_event (pop, "Destroy");
gtk_container_add (GTK_CONTAINER (win), wiz->body);
@@ -1066,11 +1037,11 @@ e_address_popup_ambiguous_email_add (EAddressPopup *pop, const GList *cards)
}
static void
-e_address_popup_multiple_matches (EAddressPopup *pop, const GList *cards)
+eab_popup_control_multiple_matches (EABPopupControl *pop, const GList *contacts)
{
pop->multiple_matches = TRUE;
- e_address_popup_ambiguous_email_add (pop, cards);
+ eab_popup_control_ambiguous_email_add (pop, contacts);
}
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
@@ -1080,71 +1051,78 @@ e_address_popup_multiple_matches (EAddressPopup *pop, const GList *cards)
*/
static void
-name_only_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
+name_only_query_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
{
- EAddressPopup *pop;
+ EABPopupControl *pop;
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS)
+ if (status != E_BOOK_ERROR_OK)
return;
- pop = E_ADDRESS_POPUP (closure);
+ pop = EAB_POPUP_CONTROL (closure);
pop->query_tag = 0;
- if (cards == NULL) {
- e_address_popup_no_matches (pop);
+ if (contacts == NULL) {
+ eab_popup_control_no_matches (pop);
} else {
- e_address_popup_ambiguous_email_add (pop, cards);
+ eab_popup_control_ambiguous_email_add (pop, contacts);
+ g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (contacts);
}
}
static void
-query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
+query_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
{
- EAddressPopup *pop;
+ EABPopupControl *pop;
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS)
+ if (status != E_BOOK_ERROR_OK)
return;
- pop = E_ADDRESS_POPUP (closure);
+ pop = EAB_POPUP_CONTROL (closure);
pop->query_tag = 0;
gtk_widget_hide (pop->query_msg);
- if (cards == NULL) {
+ if (contacts == NULL) {
/* Do a name-only query if:
(1) The name is non-empty.
(2) The e-mail is also non-empty (so that the query we just did wasn't actually a name-only query.
*/
if (pop->name && *pop->name && pop->email && *pop->email) {
- pop->query_tag = e_book_name_and_email_query (book, pop->name, NULL, name_only_query_cb, pop);
+ pop->query_tag = eab_name_and_email_query (book, pop->name, NULL, name_only_query_cb, pop);
} else {
- e_address_popup_no_matches (pop);
+ eab_popup_control_no_matches (pop);
}
} else {
- if (g_list_length ((GList *) cards) == 1)
- e_address_popup_cardify (pop, E_CARD (cards->data));
+ if (g_list_length ((GList *) contacts) == 1)
+ eab_popup_control_display_contact (pop, E_CONTACT (contacts->data));
else
- e_address_popup_multiple_matches (pop, cards);
+ eab_popup_control_multiple_matches (pop, contacts);
+
+ g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (contacts);
}
}
static void
start_query (EBook *book, EBookStatus status, gpointer closure)
{
- EAddressPopup *pop = E_ADDRESS_POPUP (closure);
+ EABPopupControl *pop = EAB_POPUP_CONTROL (closure);
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_address_popup_no_matches (pop);
+ if (status != E_BOOK_ERROR_OK) {
+ eab_popup_control_no_matches (pop);
if (book)
g_object_unref (book);
return;
}
+#if notyet
if (pop->query_tag)
e_book_simple_query_cancel (book, pop->query_tag);
+#endif
if (pop->book != book) {
g_object_ref (book);
@@ -1153,22 +1131,19 @@ start_query (EBook *book, EBookStatus status, gpointer closure)
pop->book = book;
}
- pop->query_tag = e_book_name_and_email_query (book, pop->name, pop->email, query_cb, pop);
+ pop->query_tag = eab_name_and_email_query (book, pop->name, pop->email, query_cb, pop);
g_object_unref (pop);
}
static void
-e_address_popup_query (EAddressPopup *pop)
+eab_popup_control_query (EABPopupControl *pop)
{
- EBook *book;
-
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
+ g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
- book = e_book_new ();
g_object_ref (pop);
- addressbook_load_default_book (book, start_query, pop);
+ addressbook_load_default_book (start_query, pop);
}
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
@@ -1182,16 +1157,16 @@ enum {
static void
set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
{
- EAddressPopup *pop = E_ADDRESS_POPUP (user_data);
+ EABPopupControl *pop = EAB_POPUP_CONTROL (user_data);
switch (arg_id) {
case PROPERTY_NAME:
- e_address_popup_set_name (pop, BONOBO_ARG_GET_STRING (arg));
+ eab_popup_control_set_name (pop, BONOBO_ARG_GET_STRING (arg));
break;
case PROPERTY_EMAIL:
- e_address_popup_set_email (pop, BONOBO_ARG_GET_STRING (arg));
+ eab_popup_control_set_email (pop, BONOBO_ARG_GET_STRING (arg));
break;
default:
@@ -1202,7 +1177,7 @@ set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Envi
static void
get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
{
- EAddressPopup *pop = E_ADDRESS_POPUP (user_data);
+ EABPopupControl *pop = EAB_POPUP_CONTROL (user_data);
switch (arg_id) {
@@ -1224,15 +1199,15 @@ get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environmen
}
BonoboControl *
-e_address_popup_new_control (void)
+eab_popup_control_new (void)
{
BonoboControl *control;
BonoboPropertyBag *bag;
- EAddressPopup *addy;
+ EABPopupControl *addy;
GtkWidget *w;
- w = e_address_popup_new ();
- addy = E_ADDRESS_POPUP (w);
+ w = eab_popup_new ();
+ addy = EAB_POPUP_CONTROL (w);
control = bonobo_control_new (w);
gtk_widget_show (w);
diff --git a/addressbook/gui/widgets/eab-popup-control.h b/addressbook/gui/widgets/eab-popup-control.h
new file mode 100644
index 0000000000..4d223f02cb
--- /dev/null
+++ b/addressbook/gui/widgets/eab-popup-control.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * eab-popup-control.h
+ *
+ * Copyright (C) 2001-2003, Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#ifndef __EAB_POPUP_CONTROL_H__
+#define __EAB_POPUP_CONTROL_H__
+
+#include <gtk/gtk.h>
+#include <addressbook/backend/ebook/e-book-async.h>
+#include <addressbook/backend/ebook/e-contact.h>
+#include <bonobo/bonobo-event-source.h>
+
+G_BEGIN_DECLS
+
+#define EAB_TYPE_POPUP_CONTROL (eab_popup_control_get_type ())
+#define EAB_POPUP_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_POPUP_CONTROL, EABPopupControl))
+#define EAB_POPUP_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EAB_TYPE_POPUP_CONTROL, EABPopupControlClass))
+#define EAB_IS_POPUP_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_POPUP_CONTROL))
+#define EAB_IS_POPUP_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_POPUP_CONTROL))
+
+typedef struct _EABPopupControl EABPopupControl;
+typedef struct _EABPopupControlClass EABPopupControlClass;
+
+struct _EABPopupControl {
+ GtkEventBox parent;
+
+ gchar *name;
+ gchar *email;
+
+ GtkWidget *name_widget;
+ GtkWidget *email_widget;
+ GtkWidget *query_msg;
+
+ GtkWidget *main_vbox;
+ GtkWidget *generic_view;
+ GtkWidget *contact_display;
+
+ gboolean transitory;
+
+ guint scheduled_refresh;
+ EBook *book;
+ guint query_tag;
+ gboolean multiple_matches;
+ EContact *contact;
+
+ BonoboEventSource *es;
+};
+
+struct _EABPopupControlClass {
+ GtkEventBoxClass parent_class;
+};
+
+GType eab_popup_control_get_type (void);
+
+void eab_popup_control_construct (EABPopupControl *);
+
+BonoboControl *eab_popup_control_new (void);
+
+G_END_DECLS
+
+#endif /* __EAB_POPUP_CONTROL_H__ */
+
diff --git a/addressbook/gui/widgets/e-minicard-control.c b/addressbook/gui/widgets/eab-vcard-control.c
index 7cbcfb028a..82c5fd6032 100644
--- a/addressbook/gui/widgets/e-minicard-control.c
+++ b/addressbook/gui/widgets/eab-vcard-control.c
@@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-minicard-control.c
+ * eab-vcard-control.c
*
- * Copyright (C) 1999, 2000, 2001, 2002, Ximian, Inc.
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003, Ximian, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -20,6 +20,7 @@
*
* Authors:
* Chris Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
*/
#include <config.h>
@@ -33,87 +34,22 @@
#include <gal/util/e-util.h>
#include <addressbook/gui/component/addressbook.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
+#include <addressbook/gui/widgets/eab-contact-display.h>
+#include <addressbook/backend/ebook/e-book-async.h>
+#include <addressbook/backend/ebook/e-contact.h>
+#include <addressbook/util/eab-book-util.h>
-#include "e-minicard-control.h"
-#include "e-minicard-widget.h"
-#include "e-card-merging.h"
+#include "eab-vcard-control.h"
+#include "eab-contact-merging.h"
typedef struct {
- EMinicardWidget *minicard;
+ EABContactDisplay *display;
GList *card_list;
GtkWidget *label;
-} EMinicardControl;
+ EABContactDisplayRenderMode render_mode;
+} EABVCardControl;
-#define MINICARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_MiniCard_Control"
-
-
-#if 0
-enum {
- PROP_RUNNING
-} MyArgs;
-
-#define RUNNING_KEY "Clock::Running"
-
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GObject *clock = user_data;
-
- switch (arg_id) {
-
- case PROP_RUNNING:
- {
- gboolean b = GPOINTER_TO_UINT (g_object_get_data (clock, RUNNING_KEY));
- BONOBO_ARG_SET_BOOLEAN (arg, b);
- break;
- }
-
- default:
- g_warning ("Unhandled arg %d", arg_id);
- break;
- }
-}
-
-static void
-set_prop (BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GtkClock *clock = user_data;
-
- switch (arg_id) {
-
- case PROP_RUNNING:
- {
- guint i;
-
- i = BONOBO_ARG_GET_BOOLEAN (arg);
-
- if (i)
- gtk_clock_start (clock);
- else
- gtk_clock_stop (clock);
-
- g_object_set_data (clock, RUNNING_KEY,
- GUINT_TO_POINTER (i));
- break;
- }
-
- default:
- g_warning ("Unhandled arg %d", arg_id);
- break;
- }
-}
-#endif
+#define VCARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_VCard_Control"
/*
* Bonobo::PersistStream
@@ -174,7 +110,7 @@ pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
{
GList *list;
char *vcard;
- EMinicardControl *minicard_control = data;
+ EABVCardControl *vcard_control = data;
if (type && g_ascii_strcasecmp (type, "text/vCard") != 0 &&
g_ascii_strcasecmp (type, "text/x-vCard") != 0) {
@@ -189,27 +125,27 @@ pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
return;
}
- e_free_object_list (minicard_control->card_list);
- list = e_card_load_cards_from_string_with_default_charset(vcard, "ISO-8859-1");
+ e_free_object_list (vcard_control->card_list);
+ list = eab_contact_list_from_string (vcard);
g_free(vcard);
- minicard_control->card_list = list;
- if (list)
- g_object_set(minicard_control->minicard,
- "card", list->data,
- NULL);
+ vcard_control->card_list = list;
+ if (list) {
+ eab_contact_display_render (vcard_control->display, E_CONTACT (list->data),
+ vcard_control->render_mode);
+ }
if (list && list->next) {
char *message;
int length = g_list_length (list) - 1;
if (length > 1) {
- message = g_strdup_printf (_("and %d other cards."), length);
+ message = g_strdup_printf (_("and %d other contacts."), length);
} else {
- message = g_strdup_printf (_("and one other card."));
+ message = g_strdup_printf (_("and one other contact."));
}
- gtk_label_set_text (GTK_LABEL (minicard_control->label), message);
+ gtk_label_set_text (GTK_LABEL (vcard_control->label), message);
g_free (message);
- gtk_widget_show (minicard_control->label);
+ gtk_widget_show (vcard_control->label);
} else {
- gtk_widget_hide (minicard_control->label);
+ gtk_widget_hide (vcard_control->label);
}
} /* pstream_load */
@@ -221,7 +157,7 @@ pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
Bonobo_Persist_ContentType type, void *data,
CORBA_Environment *ev)
{
- EMinicardControl *minicard_control = data;
+ EABVCardControl *vcard_control = data;
char *vcard;
int length;
@@ -232,7 +168,7 @@ pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
return;
}
- vcard = e_card_list_get_vcard(minicard_control->card_list);
+ vcard = eab_contact_list_to_string (vcard_control->card_list);
length = strlen (vcard);
bonobo_stream_client_write (stream, vcard, length, ev);
g_free (vcard);
@@ -249,10 +185,11 @@ static void
book_open_cb (EBook *book, EBookStatus status, gpointer closure)
{
GList *list = closure;
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (status == E_BOOK_ERROR_OK) {
GList *p;
for (p = list; p; p = p->next) {
- e_card_merging_book_add_card(book, p->data, NULL, NULL);
+ /* XXX argh, more passing of NULL's for callbacks */
+ eab_merging_book_add_contact (book, E_CONTACT (p->data), NULL, NULL);
}
}
if (book)
@@ -263,87 +200,103 @@ book_open_cb (EBook *book, EBookStatus status, gpointer closure)
static void
save_in_addressbook(GtkWidget *button, gpointer data)
{
- EMinicardControl *minicard_control = data;
+ EABVCardControl *vcard_control = data;
GList *list, *p;
- EBook *book;
-
- book = e_book_new ();
- list = g_list_copy (minicard_control->card_list);
+ list = g_list_copy (vcard_control->card_list);
for (p = list; p; p = p->next)
g_object_ref (p->data);
- addressbook_load_default_book (book, book_open_cb, list);
+ addressbook_load_default_book (book_open_cb, list);
+}
+
+static void
+toggle_full_vcard(GtkWidget *button, gpointer data)
+{
+ EABVCardControl *vcard_control = data;
+ char *label;
+
+ if (!vcard_control->card_list)
+ return;
+
+ if (vcard_control->render_mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
+ vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
+ label = _("Show Full VCard");
+ }
+ else {
+ vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ label = _("Show Compact VCard");
+ }
+
+ gtk_button_set_label (GTK_BUTTON (button), label);
+ eab_contact_display_render (vcard_control->display, E_CONTACT (vcard_control->card_list->data),
+ vcard_control->render_mode);
}
static void
free_struct (gpointer data, GObject *where_object_was)
{
- EMinicardControl *minicard_control = data;
- e_free_object_list (minicard_control->card_list);
- g_free (minicard_control);
+ EABVCardControl *vcard_control = data;
+ e_free_object_list (vcard_control->card_list);
+ g_free (vcard_control);
}
BonoboControl *
-e_minicard_control_new (void)
+eab_vcard_control_new (void)
{
-#if 0
- BonoboPropertyBag *pb;
-#endif
BonoboControl *control;
BonoboPersistStream *stream;
- GtkWidget *minicard;
- GtkWidget *button;
+ GtkWidget *display;
+ GtkWidget *button1, *button2;
GtkWidget *label;
- GtkWidget *vbox;
+ GtkWidget *table;
- EMinicardControl *minicard_control = g_new (EMinicardControl, 1);
+ EABVCardControl *vcard_control = g_new (EABVCardControl, 1);
+ printf ("inside eab_vcard_control_new\n");
- minicard_control->card_list = NULL;
- minicard_control->minicard = NULL;
- minicard_control->label = NULL;
+ vcard_control->card_list = NULL;
+ vcard_control->display = NULL;
+ vcard_control->label = NULL;
+
+ vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
/* Create the control. */
- minicard = e_minicard_widget_new ();
- gtk_widget_show (minicard);
- minicard_control->minicard = E_MINICARD_WIDGET (minicard);
+ display = eab_contact_display_new ();
+ gtk_widget_show (display);
+ vcard_control->display = EAB_CONTACT_DISPLAY (display);
/* This is intentionally not shown. */
label = gtk_label_new ("");
- minicard_control->label = label;
+ vcard_control->label = label;
+
+ button1 = gtk_button_new_with_label(_("Show Full VCard"));
+ g_signal_connect (button1, "clicked",
+ G_CALLBACK (toggle_full_vcard), vcard_control);
+ gtk_widget_show (button1);
- button = gtk_button_new_with_label(_("Save in addressbook"));
- g_signal_connect (button, "clicked",
- G_CALLBACK (save_in_addressbook), minicard_control);
- gtk_widget_show (button);
+ button2 = gtk_button_new_with_label(_("Save in addressbook"));
+ g_signal_connect (button2, "clicked",
+ G_CALLBACK (save_in_addressbook), vcard_control);
+ gtk_widget_show (button2);
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), minicard, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- gtk_widget_show (vbox);
+ table = gtk_table_new (6, 6, FALSE);
+ gtk_table_attach (GTK_TABLE (table), display, 0, 6, 3, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 3, 2, 3, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), button1, 0, 1, 1, 2, 0, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), button2, 1, 2, 1, 2, 0, 0, 0, 0);
+ gtk_widget_show (table);
- control = bonobo_control_new (vbox);
+ control = bonobo_control_new (table);
- g_object_weak_ref (G_OBJECT (control), free_struct, minicard_control);
+ g_object_weak_ref (G_OBJECT (control), free_struct, vcard_control);
stream = bonobo_persist_stream_new (pstream_load, pstream_save,
pstream_get_content_types,
- MINICARD_CONTROL_ID,
- minicard_control);
-
-#if 0
- /* Create the properties. */
- pb = bonobo_property_bag_new (get_prop, set_prop, clock);
- bonobo_control_set_properties (control, pb);
-
- bonobo_property_bag_add (pb, "running", PROP_RUNNING,
- BONOBO_ARG_BOOLEAN, NULL,
- "Whether or not the clock is running", 0);
-#endif
+ VCARD_CONTROL_ID,
+ vcard_control);
if (stream == NULL) {
bonobo_object_unref (BONOBO_OBJECT (control));
diff --git a/addressbook/gui/widgets/eab-vcard-control.h b/addressbook/gui/widgets/eab-vcard-control.h
new file mode 100644
index 0000000000..5f6643c1ca
--- /dev/null
+++ b/addressbook/gui/widgets/eab-vcard-control.h
@@ -0,0 +1,8 @@
+#ifndef __EAB_VCARD_CONTROL_H__
+#define __EAB_VCARD_CONTROL_H__
+
+#include <bonobo/bonobo-control.h>
+
+BonoboControl *eab_vcard_control_new (void);
+
+#endif /* __EAB_VCARD_CONTROL_H__ */
diff --git a/addressbook/gui/widgets/test-minicard-label.c b/addressbook/gui/widgets/test-minicard-label.c
deleted file mode 100644
index c109497628..0000000000
--- a/addressbook/gui/widgets/test-minicard-label.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard-label.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <libgnomeui/gnome-init.h>
-#include <gal/widgets/e-canvas.h>
-#include "e-minicard-label.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *label;
-GnomeCanvasItem *rect;
-
-static void destroy_callback(gpointer data, GObject *where_object_was)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, allocation->width, allocation->height );
- gnome_canvas_item_set( label,
- "width", (double) allocation->width,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( rect,
- "x2", (double) allocation->width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-#if 0
-static void about_callback( GtkWidget *widget, gpointer data )
-{
-
- const gchar *authors[] =
- {
- "Christopher James Lahey <clahey@umich.edu>",
- NULL
- };
-
- GtkWidget *about =
- gnome_about_new ( _( "Minicard Label Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard label canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-static void button_press_callback( GtkWidget *widget, gpointer data )
-{
- gnome_canvas_item_grab_focus( label );
-}
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Label Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Label Test", NULL);
-
- canvas = e_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- label = e_minicard_label_new(gnome_canvas_root( GNOME_CANVAS( canvas ) ));
- gnome_canvas_item_set( label,
- "width", (double) 100,
- "height", (double) 100,
- "fieldname", "Full Name:",
- "field", "Christopher James Lahey",
- NULL );
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gnome_app_set_contents( GNOME_APP( app ), canvas );
-
-
- /* Connect the signals */
- g_object_weak_ref (app, destroy_callback, app);
-
- g_signal_connect( canvas , "size_allocate",
- G_CALLBACK ( allocate_callback ),
- ( gpointer ) app );
-
- g_signal_connect( canvas , "button_press_event",
- G_CALLBACK ( button_press_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-minicard-view.c b/addressbook/gui/widgets/test-minicard-view.c
deleted file mode 100644
index 14ede54208..0000000000
--- a/addressbook/gui/widgets/test-minicard-view.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-reflow.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <libgnorba/gnorba.h>
-#include <e-util/e-canvas.h>
-#include "e-minicard-view.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *reflow;
-GnomeCanvasItem *rect;
-GtkAllocation last_alloc;
-
-CORBA_Environment ev;
-CORBA_ORB orb;
-
-static void
-init_bonobo (int argc, char **argv)
-{
-
- gnome_CORBA_init_with_popt_table (
- "Reflow Test", VERSION,
- &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
-
- orb = gnome_CORBA_ORB ();
-
- if (bonobo_init (orb, NULL, NULL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
-}
-
-static void destroy_callback(gpointer data, GObject *where_object_was)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- double width;
- last_alloc = *allocation;
- gnome_canvas_item_set( reflow,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( reflow,
- "minimum_width", (double) allocation->width,
- NULL );
- g_object_get(reflow,
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, width, allocation->height );
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-static void resize(GnomeCanvas *canvas, gpointer data)
-{
- double width;
- g_object_get(reflow,
- "width", &width,
- NULL);
- width = MAX(width, last_alloc.width);
- gnome_canvas_set_scroll_region(canvas , 0, 0, width, last_alloc.height );
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) last_alloc.height,
- NULL );
-}
-
-#if 0
-static void about_callback( GtkWidget *widget, gpointer data )
-{
-
- const gchar *authors[] =
- {
- "Christopher James Lahey <clahey@umich.edu>",
- NULL
- };
-
- GtkWidget *about =
- gnome_about_new ( _( "Reflow Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the reflow canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- if (status == E_BOOK_STATUS_SUCCESS)
- gnome_canvas_item_set(reflow,
- "book", book,
- NULL);
-}
-
-static gboolean
-ebook_create (gpointer data)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- G_GNUC_FUNCTION);
- return FALSE;
- }
-
-
- e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL);
-
- return FALSE;
-}
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- GtkWidget *vbox;
- GtkWidget *scrollbar;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- CORBA_exception_init (&ev);
- init_bonobo (argc, argv);
-
- app = gnome_app_new("Reflow Test", NULL);
-
- vbox = gtk_vbox_new(FALSE, 0);
-
- canvas = e_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- reflow = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- e_minicard_view_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
- NULL );
- g_signal_connect( canvas, "reflow",
- G_CALLBACK ( resize ),
- ( gpointer ) app);
-
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gtk_box_pack_start(GTK_BOX(vbox), canvas, TRUE, TRUE, 0);
-
- scrollbar = gtk_hscrollbar_new(gtk_layout_get_hadjustment(GTK_LAYOUT(canvas)));
-
- gtk_box_pack_start(GTK_BOX(vbox), scrollbar, FALSE, FALSE, 0);
-
- gnome_app_set_contents( GNOME_APP( app ), vbox );
-
- /* Connect the signals */
- g_object_weak_ref (app, destroy_callback, app);
-
- g_signal_connect( canvas, "size_allocate",
- G_CALLBACK ( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
- gdk_window_set_back_pixmap( GTK_LAYOUT(canvas)->bin_window, NULL, FALSE);
-
- g_idle_add (ebook_create, NULL);
-
- bonobo_main ();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-minicard.c b/addressbook/gui/widgets/test-minicard.c
deleted file mode 100644
index 822362d972..0000000000
--- a/addressbook/gui/widgets/test-minicard.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@ximian.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-
-#include "e-minicard.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *card;
-GnomeCanvasItem *rect;
-
-static void destroy_callback(gpointer data, GObject *where_object_was)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, allocation->width, allocation->height );
- gnome_canvas_item_set( card,
- "width", (double) allocation->width,
- NULL );
- gnome_canvas_item_set( rect,
- "x2", (double) allocation->width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-#if 0
-static void about_callback( GtkWidget *widget, gpointer data )
-{
-
- const gchar *authors[] =
- {
- "Christopher James Lahey <clahey@umich.edu>",
- NULL
- };
-
- GtkWidget *about =
- gnome_about_new ( _( "Minicard Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- int i;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Test", NULL);
-
- canvas = gnome_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- for ( i = 0; i < 1; i++ )
- {
- card = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- e_minicard_get_type(),
- "width", (double) 100,
- NULL );
- }
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gnome_app_set_contents( GNOME_APP( app ), canvas );
-
- /* Connect the signals */
- g_object_weak_ref (app, destroy_callback, app);
-
- g_signal_connect( canvas, "size_allocate",
- G_CALLBACK( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/printing/Makefile.am b/addressbook/printing/Makefile.am
index b28d841ec2..f9e9661890 100644
--- a/addressbook/printing/Makefile.am
+++ b/addressbook/printing/Makefile.am
@@ -38,16 +38,18 @@ contact_print_test_SOURCES = \
test-print.c
contact_print_test_LDADD = \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
libecontactprint.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/backend/ebook/libebook.la \
$(EVOLUTION_ADDRESSBOOK_LIBS)
contact_print_style_editor_test_SOURCES = \
test-contact-print-style-editor.c
contact_print_style_editor_test_LDADD = \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
libecontactprint.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/backend/ebook/libebook.la \
$(EVOLUTION_ADDRESSBOOK_LIBS)
diff --git a/addressbook/printing/e-contact-print-envelope.c b/addressbook/printing/e-contact-print-envelope.c
index 93916744da..c7bd68163f 100644
--- a/addressbook/printing/e-contact-print-envelope.c
+++ b/addressbook/printing/e-contact-print-envelope.c
@@ -29,8 +29,6 @@
#include <libgnomeprint/gnome-print.h>
#include <libgnomeprint/gnome-print-job.h>
#include <libgnomeprintui/gnome-print-job-preview.h>
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
#define ENVELOPE_HEIGHT (72.0 * 4.0)
#define ENVELOPE_WIDTH (72.0 * 9.5)
@@ -131,9 +129,8 @@ e_contact_print_envelope_close(GnomeDialog *dialog, gpointer data)
}
static void
-ecpe_print(GnomePrintContext *pc, ECard *ecard, gboolean as_return)
+ecpe_print(GnomePrintContext *pc, EContact *contact, gboolean as_return)
{
- ECardSimple *card = e_card_simple_new(ecard);
char *address;
EcpeLine *linelist;
double x;
@@ -144,7 +141,7 @@ ecpe_print(GnomePrintContext *pc, ECard *ecard, gboolean as_return)
gnome_print_rotate(pc, 90);
gnome_print_translate(pc, 72.0 * 11.0 - ENVELOPE_WIDTH, -72.0 * 8.5 + (72.0 * 8.5 - ENVELOPE_HEIGHT) / 2);
- address = e_card_simple_get(card, E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS);
+ address = e_contact_get(contact, E_CONTACT_ADDRESS_LABEL_WORK);
linelist = ecpe_break(address);
if (as_return)
font = gnome_font_find ("Sans", 9);
@@ -166,8 +163,6 @@ ecpe_print(GnomePrintContext *pc, ECard *ecard, gboolean as_return)
gnome_print_showpage(pc);
gnome_print_context_close(pc);
-
- g_object_unref(card);
}
static void
@@ -176,10 +171,10 @@ e_contact_print_envelope_button(GnomeDialog *dialog, gint button, gpointer data)
GnomePrintJob *master;
GnomePrintContext *pc;
GnomePrintConfig *config;
- ECard *card = NULL;
+ EContact *contact = NULL;
GtkWidget *preview;
- card = g_object_get_data(G_OBJECT(dialog), "card");
+ contact = g_object_get_data(G_OBJECT(dialog), "contact");
switch( button ) {
case GNOME_PRINT_DIALOG_RESPONSE_PRINT:
@@ -187,7 +182,7 @@ e_contact_print_envelope_button(GnomeDialog *dialog, gint button, gpointer data)
master = gnome_print_job_new (config);
pc = gnome_print_job_get_context( master );
- ecpe_print(pc, card, FALSE);
+ ecpe_print(pc, contact, FALSE);
gnome_print_job_print(master);
gnome_dialog_close(dialog);
@@ -197,27 +192,27 @@ e_contact_print_envelope_button(GnomeDialog *dialog, gint button, gpointer data)
master = gnome_print_job_new (config);
pc = gnome_print_job_get_context( master );
- ecpe_print(pc, card, FALSE);
+ ecpe_print(pc, contact, FALSE);
preview = GTK_WIDGET(gnome_print_job_preview_new(master, "Print Preview"));
gtk_widget_show_all(preview);
break;
case GNOME_PRINT_DIALOG_RESPONSE_CANCEL:
- g_object_unref(card);
+ g_object_unref(contact);
gnome_dialog_close(dialog);
break;
}
}
GtkWidget *
-e_contact_print_envelope_dialog_new(ECard *card)
+e_contact_print_envelope_dialog_new(EContact *contact)
{
GtkWidget *dialog;
dialog = gnome_print_dialog_new(NULL, _("Print envelope"), GNOME_PRINT_DIALOG_COPIES);
- card = e_card_duplicate(card);
- g_object_set_data(G_OBJECT(dialog), "card", card);
+ contact = e_contact_duplicate(contact);
+ g_object_set_data(G_OBJECT(dialog), "contact", contact);
g_signal_connect(dialog,
"clicked", G_CALLBACK(e_contact_print_envelope_button), NULL);
g_signal_connect(dialog,
@@ -230,15 +225,15 @@ GtkWidget *
e_contact_print_envelope_list_dialog_new(GList *list)
{
GtkWidget *dialog;
- ECard *card;
+ EContact *contact;
if (list == NULL)
return NULL;
dialog = gnome_print_dialog_new(NULL, _("Print envelope"), GNOME_PRINT_DIALOG_COPIES);
- card = e_card_duplicate(list->data);
- g_object_set_data(G_OBJECT(dialog), "card", card);
+ contact = e_contact_duplicate(list->data);
+ g_object_set_data(G_OBJECT(dialog), "contact", contact);
g_signal_connect(dialog,
"clicked", G_CALLBACK(e_contact_print_envelope_button), NULL);
g_signal_connect(dialog,
diff --git a/addressbook/printing/e-contact-print-envelope.h b/addressbook/printing/e-contact-print-envelope.h
index 4302c4c5d7..d9e24b1794 100644
--- a/addressbook/printing/e-contact-print-envelope.h
+++ b/addressbook/printing/e-contact-print-envelope.h
@@ -22,11 +22,11 @@
#ifndef E_CONTACT_PRINT_ENVELOPE_H
#define E_CONTACT_PRINT_ENVELOPE_H
-#include <addressbook/backend/ebook/e-card.h>
+#include <addressbook/backend/ebook/e-contact.h>
#include <gtk/gtkwidget.h>
#include "e-contact-print-types.h"
-GtkWidget *e_contact_print_envelope_dialog_new(ECard *card);
+GtkWidget *e_contact_print_envelope_dialog_new(EContact *contact);
GtkWidget *e_contact_print_envelope_list_dialog_new(GList *list);
#endif /* E_CONTACT_PRINT_ENVELOPE_H */
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c
index 81698ddb10..0aa2e67900 100644
--- a/addressbook/printing/e-contact-print.c
+++ b/addressbook/printing/e-contact-print.c
@@ -38,10 +38,9 @@
#include <libgnomeprint/gnome-print-job.h>
#include <libgnomeprintui/gnome-print-dialog.h>
#include <libgnomeprintui/gnome-print-job-preview.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <addressbook/backend/ebook/e-card-simple.h>
-#include <addressbook/backend/ebook/e-destination.h>
+#include <addressbook/backend/ebook/e-book-async.h>
+#include <addressbook/backend/ebook/e-contact.h>
+#include <addressbook/util/eab-destination.h>
#define SCALE 5
#define HYPHEN_PIXELS 20
@@ -70,7 +69,7 @@ struct _EContactPrintContext
EBook *book;
gchar *query;
- GList *cards;
+ GList *contacts;
};
static gint
@@ -274,7 +273,7 @@ e_contact_output(GnomePrintContext *pc, GnomeFont *font, double x, double y, dou
}
static gdouble
-e_contact_text_height(GnomePrintContext *pc, GnomeFont *font, double width, gchar *text)
+e_contact_text_height(GnomePrintContext *pc, GnomeFont *font, double width, const gchar *text)
{
int line_count = e_contact_divide_text(pc, font, width, text, NULL);
return line_count * (gnome_font_get_ascender(font) + gnome_font_get_descender(font)) +
@@ -402,12 +401,12 @@ e_contact_start_new_page(EContactPrintContext *ctxt)
}
static double
-e_contact_get_card_size(ECardSimple *simple, EContactPrintContext *ctxt)
+e_contact_get_contact_size(EContact *contact, EContactPrintContext *ctxt)
{
gdouble height = 0;
gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
gdouble column_width;
- char *file_as;
+ const char *file_as;
gint field;
if ( ctxt->style->letter_tabs )
page_width -= e_contact_get_letter_tab_width(ctxt);
@@ -417,22 +416,20 @@ e_contact_get_card_size(ECardSimple *simple, EContactPrintContext *ctxt)
height += gnome_font_get_size (ctxt->style->headings_font) * .2;
- g_object_get(simple->card,
- "file_as", &file_as,
- NULL);
+ file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+
height += e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, file_as);
- g_free (file_as);
height += gnome_font_get_size (ctxt->style->headings_font) * .2;
height += gnome_font_get_size (ctxt->style->headings_font) * .2;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; field++) {
+ for(field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
char *string;
- string = e_card_simple_get(simple, field);
+ string = e_contact_get(contact, field);
if (string && *string) {
double xoff = 0;
- xoff += gnome_font_get_width_utf8(ctxt->style->body_font, e_card_simple_get_name(simple, field));
+ xoff += gnome_font_get_width_utf8(ctxt->style->body_font, e_contact_pretty_name (field));
xoff += gnome_font_get_width_utf8(ctxt->style->body_font, ": ");
height += e_contact_text_height(ctxt->pc, ctxt->style->body_font, column_width - xoff, string);
height += .2 * gnome_font_get_size (ctxt->style->body_font);
@@ -447,7 +444,7 @@ e_contact_get_card_size(ECardSimple *simple, EContactPrintContext *ctxt)
static void
-e_contact_print_card (ECardSimple *simple, EContactPrintContext *ctxt)
+e_contact_print_contact (EContact *contact, EContactPrintContext *ctxt)
{
gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
gdouble column_width;
@@ -463,9 +460,7 @@ e_contact_print_card (ECardSimple *simple, EContactPrintContext *ctxt)
ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
- g_object_get(simple->card,
- "file_as", &file_as,
- NULL);
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
if (ctxt->style->print_using_grey)
e_contact_rectangle(ctxt->pc, ctxt->x, ctxt->y + gnome_font_get_size (ctxt->style->headings_font) * .3, ctxt->x + column_width, ctxt->y - e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, file_as) - gnome_font_get_size (ctxt->style->headings_font) * .3, .85, .85, .85);
e_contact_output(ctxt->pc, ctxt->style->headings_font, ctxt->x + 2, ctxt->y, column_width - 4, file_as);
@@ -475,14 +470,14 @@ e_contact_print_card (ECardSimple *simple, EContactPrintContext *ctxt)
ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; field++) {
+ for(field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
char *string;
- string = e_card_simple_get(simple, field);
+ string = e_contact_get(contact, field);
if (string && !strncmp (string, "<?xml", 4)) {
- EDestination *dest = e_destination_import (string);
+ EABDestination *dest = eab_destination_import (string);
if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
+ gchar *new_string = g_strdup (eab_destination_get_address (dest));
g_free (string);
string = new_string;
g_object_unref (dest);
@@ -491,8 +486,8 @@ e_contact_print_card (ECardSimple *simple, EContactPrintContext *ctxt)
if (string && *string) {
double xoff = 0;
- e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, e_card_simple_get_name(simple, field));
- xoff += gnome_font_get_width_utf8(ctxt->style->body_font, e_card_simple_get_name(simple, field));
+ e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, e_contact_pretty_name (field));
+ xoff += gnome_font_get_width_utf8(ctxt->style->body_font, e_contact_pretty_name (field));
e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, ": ");
xoff += gnome_font_get_width_utf8(ctxt->style->body_font, ": ");
e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, column_width - xoff, string);
@@ -526,7 +521,7 @@ e_contact_start_new_column (EContactPrintContext *ctxt)
static void
complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintContext *ctxt)
{
- GList *cards = ctxt->cards;
+ GList *contacts = ctxt->contacts;
gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
@@ -541,15 +536,13 @@ complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintCon
gnome_print_beginpage (ctxt->pc, NULL);
- for(; cards; cards = cards->next) {
- ECard *card = cards->data;
- ECardSimple *simple = e_card_simple_new(card);
+ for(; contacts; contacts = contacts->next) {
+ EContact *contact = contacts->data;
guchar *file_as;
gchar *letter_str = NULL;
- g_object_get(card,
- "file_as", &file_as,
- NULL);
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+
if (file_as != NULL) {
letter_str = g_strndup (file_as, g_utf8_next_char (file_as) - (gchar *) file_as);
}
@@ -559,13 +552,13 @@ complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintCon
if (ctxt->style->sections_start_new_page && ! ctxt->first_contact) {
e_contact_start_new_page(ctxt);
}
- else if ((!ctxt->first_contact) && (ctxt->y - e_contact_get_letter_heading_height(ctxt) - e_contact_get_card_size(simple, ctxt) < ctxt->style->bottom_margin * 72))
+ else if ((!ctxt->first_contact) && (ctxt->y - e_contact_get_letter_heading_height(ctxt) - e_contact_get_contact_size(contact, ctxt) < ctxt->style->bottom_margin * 72))
e_contact_start_new_column(ctxt);
if ( ctxt->style->letter_headings )
e_contact_print_letter_heading(ctxt, ctxt->character);
ctxt->first_section = FALSE;
}
- else if ( (!ctxt->first_contact) && (ctxt->y - e_contact_get_card_size(simple, ctxt) < ctxt->style->bottom_margin * 72)) {
+ else if ( (!ctxt->first_contact) && (ctxt->y - e_contact_get_contact_size(contact, ctxt) < ctxt->style->bottom_margin * 72)) {
e_contact_start_new_column(ctxt);
if ( ctxt->style->letter_headings )
e_contact_print_letter_heading(ctxt, ctxt->character);
@@ -574,9 +567,8 @@ complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintCon
ctxt->last_char_on_page = toupper(*file_as);
if ( ctxt->last_char_on_page < ctxt->first_char_on_page )
ctxt->first_char_on_page = ctxt->last_char_on_page;
- e_contact_print_card(simple, ctxt);
+ e_contact_print_contact(contact, ctxt);
ctxt->first_contact = FALSE;
- g_object_unref(simple);
}
ctxt->last_char_on_page = 'Z';
if ( ctxt->style->letter_tabs )
@@ -598,8 +590,8 @@ complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintCon
if (ctxt->book)
g_object_unref(ctxt->book);
g_free(ctxt->query);
- g_list_foreach(ctxt->cards, (GFunc) g_object_unref, NULL);
- g_list_free(ctxt->cards);
+ g_list_foreach(ctxt->contacts, (GFunc) g_object_unref, NULL);
+ g_list_free(ctxt->contacts);
g_object_unref(ctxt->style->headings_font);
g_object_unref(ctxt->style->body_font);
g_object_unref(ctxt->style->header_font);
@@ -611,41 +603,32 @@ complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintCon
}
static int
-card_compare (ECard *card1, ECard *card2) {
- int cmp = 0;
-
- if (card1 && card2) {
- char *file_as1, *file_as2;
-
- g_object_get(card1,
- "file_as", &file_as1,
- NULL);
- g_object_get(card2,
- "file_as", &file_as2,
- NULL);
- if (file_as1 && file_as2)
- cmp = g_utf8_collate(file_as1, file_as2);
- else if (file_as1)
- cmp = -1;
- else if (file_as2)
- cmp = 1;
- else
- cmp = strcmp(e_card_get_id(card1), e_card_get_id(card2));
-
- g_free (file_as2);
- g_free (file_as1);
+contact_compare (EContact *contact1, EContact *contact2)
+{
+ if (contact1 && contact2) {
+ const char *file_as1, *file_as2;
+ file_as1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
+ file_as2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
+ if (file_as1 && file_as2)
+ return g_utf8_collate(file_as1, file_as2);
+ if (file_as1)
+ return -1;
+ if (file_as2)
+ return 1;
+ return strcmp(e_contact_get_const(contact1, E_CONTACT_UID), e_contact_get_const(contact2, E_CONTACT_UID));
+ } else {
+ return 0;
}
- return cmp;
}
static void
-create_card(EBookView *book_view, const GList *cards, EContactPrintContext *ctxt)
+create_contact(EBookView *book_view, const GList *contacts, EContactPrintContext *ctxt)
{
- for(; cards; cards = cards->next) {
- ECard *card = cards->data;
- g_object_ref(card);
- ctxt->cards = g_list_insert_sorted(ctxt->cards, card, (GCompareFunc) card_compare);
+ for(; contacts; contacts = contacts->next) {
+ EContact *contact = contacts->data;
+ g_object_ref(contact);
+ ctxt->contacts = g_list_insert_sorted(ctxt->contacts, contact, (GCompareFunc) contact_compare);
}
}
@@ -655,169 +638,31 @@ book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, EContac
g_object_ref(book_view);
g_signal_connect(book_view,
- "card_added",
- G_CALLBACK(create_card),
+ "contacts_added",
+ G_CALLBACK(create_contact),
ctxt);
g_signal_connect(book_view,
"sequence_complete",
G_CALLBACK(complete_sequence),
ctxt);
-}
-
-static void
-e_contact_do_print_cards (EBook *book, char *query, EContactPrintContext *ctxt)
-{
- e_book_get_book_view(book, query, (EBookBookViewCallback) book_view_loaded, ctxt);
-}
-
-#if 0
-static double
-e_contact_get_phone_list_size(ECardSimple *simple, EContactPrintContext *ctxt)
-{
- double height = 0;
- int field;
-
- height += gnome_font_get_size (ctxt->style->headings_font) * .2;
-
- height += gnome_font_get_size (ctxt->style->headings_font) * .2;
-
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; field++) {
- char *string;
- string = e_card_simple_get(simple, field);
- if (string && *string) {
- if ( 1 ) /* field is a phone field. */ {
- gchar *field = string;
- height += e_contact_text_height(ctxt->pc, ctxt->style->body_font, 100, field);
- height += .2 * gnome_font_get_size (ctxt->style->body_font);
- }
- }
- g_free(string);
- }
- height += gnome_font_get_size (ctxt->style->headings_font) * .4;
- return height;
-}
-
-
-static void
-e_contact_print_phone_list (ECard *card, EContactPrintContext *ctxt)
-{
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble column_width;
- double xoff, dotwidth;
- int dotcount;
- char *dots;
- int i;
- char *file_as;
- if ( ctxt->style->letter_tabs )
- page_width -= e_contact_get_letter_tab_width(ctxt);
- column_width = (page_width + 18) / ctxt->style->num_columns - 18;
-
- gnome_print_gsave(ctxt->pc);
-
- ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
- ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .2;
- e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x, ctxt->y, -1, e_card_get_string_fileas(card));
-
- xoff = column_width - 9 * gnome_font_get_size (ctxt->style->body_font);
- dotwidth = xoff -
- gnome_font_get_width_utf8(ctxt->style->body_font, e_card_get_string_fileas(card)) -
- gnome_font_get_width_utf8(ctxt->style->body_font, " ");
- dotcount = dotwidth / gnome_font_get_width(ctxt->style->body_font, '.');
- dots = g_new(gchar, dotcount + 1);
- for (i = 0; i < dotcount; i++)
- dots[i] = '.';
- dots[dotcount] = 0;
- e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff - dotcount * gnome_font_get_width(ctxt->style->body_font, '.'), ctxt->y, -1, dots);
- g_free(dots);
-
- for(; shown_fields; shown_fields = g_list_next(shown_fields)) {
- if ( 1 ) /* field is a phone field. */ {
- gchar *field = e_card_get_string(card, shown_fields->data);
- e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, shown_fields->data);
- e_contact_output(ctxt->pc, ctxt->style->body_font,
- ctxt->x + column_width - gnome_font_get_width_utf8(ctxt->style->body_font,
- field),
- ctxt->y,
- -1,
- field);
- ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->body_font, 100, field);
- ctxt->y -= .2 * gnome_font_get_size (ctxt->style->body_font);
- }
- }
- ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .4;
- gnome_print_grestore(ctxt->pc);
+ e_book_view_start (book_view);
}
static void
-e_contact_do_print_phone_list (EBook *book, char *query, EContactPrintContext *ctxt)
+e_contact_do_print_contacts (EBook *book, char *query, EContactPrintContext *ctxt)
{
- ECard *card = NULL;
- int i;
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble column_width;
- ctxt->first_contact = TRUE;
- ctxt->character = NULL;
- ctxt->y = (ctxt->style->page_height - ctxt->style->top_margin) * 72;
- ctxt->x = (ctxt->style->left_margin) * 72;
- if ( ctxt->style->letter_tabs )
- page_width -= e_contact_get_letter_tab_width(ctxt);
-
- ctxt->first_char_on_page = 'A' - 1;
-
- column_width = (page_width + 18) / ctxt->style->num_columns - 18;
- /*
- for(card = e_book_get_first(book); card; card = e_book_get_next(book)) {
- */
- for (i=0; i < 30; i++) {
- guchar *file_as = e_card_get_string_fileas(card);
- if ( file_as && (!character || *character != tolower(*file_as)) ) {
- if (ctxt->style->sections_start_new_page && ! first_contact) {
- e_contact_start_new_page(ctxt);
- }
- else if ((!first_contact) && (ctxt->y - e_contact_get_letter_heading_height(ctxt) - e_contact_get_phone_list_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72))
- e_contact_start_new_column(ctxt);
- if (!character)
- character = g_strdup(" ");
- *character = tolower(*file_as);
- if ( ctxt->style->letter_headings )
- e_contact_print_letter_heading(ctxt, character);
- ctxt->first_section = FALSE;
- }
- else if ( (!first_contact) && (ctxt->y - e_contact_get_card_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72)) {
- e_contact_start_new_column(ctxt);
- if ( ctxt->style->letter_headings )
- e_contact_print_letter_heading(ctxt, character);
- }
- ctxt->last_char_on_page = toupper(*file_as);
- if ( ctxt->last_char_on_page < ctxt->first_char_on_page )
- ctxt->first_char_on_page = ctxt->last_char_on_page;
- e_contact_print_phone_list(card, ctxt, shown_fields);
- first_contact = FALSE;
- g_free (file_as);
- }
- ctxt->last_char_on_page = 'Z';
- if ( ctxt->style->letter_tabs )
- e_contact_print_letter_tab(ctxt);
- gnome_print_showpage(ctxt->pc);
- gnome_print_context_close(ctxt->pc);
- g_free(character);
+ e_book_async_get_book_view(book, query, (EBookBookViewCallback) book_view_loaded, ctxt);
}
-#endif
static void
e_contact_do_print (EBook *book, char *query, EContactPrintContext *ctxt)
{
switch ( ctxt->style->type ) {
case E_CONTACT_PRINT_TYPE_CARDS:
- e_contact_do_print_cards( book, query, ctxt);
+ e_contact_do_print_contacts( book, query, ctxt);
break;
-#if 0
- case E_CONTACT_PRINT_TYPE_PHONE_LIST:
- e_contact_do_print_phone_list( book, query, ctxt );
- break;
-#endif
default:
break;
}
@@ -1027,8 +872,8 @@ e_contact_print_response(GtkWidget *dialog, gint response_id, gpointer data)
gboolean uses_list = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dialog), "uses_list"));
EBook *book = NULL;
char *query = NULL;
- ECard *card = NULL;
- GList *card_list = NULL;
+ EContact *contact = NULL;
+ GList *contact_list = NULL;
gdouble font_size;
@@ -1037,10 +882,10 @@ e_contact_print_response(GtkWidget *dialog, gint response_id, gpointer data)
query = g_object_get_data(G_OBJECT(dialog), "query");
}
else if (uses_list) {
- card_list = g_object_get_data(G_OBJECT(dialog), "card_list");
+ contact_list = g_object_get_data(G_OBJECT(dialog), "contact_list");
}
else {
- card = g_object_get_data(G_OBJECT(dialog), "card");
+ contact = g_object_get_data(G_OBJECT(dialog), "contact");
}
switch( response_id ) {
case GNOME_PRINT_DIALOG_RESPONSE_PRINT:
@@ -1075,16 +920,16 @@ e_contact_print_response(GtkWidget *dialog, gint response_id, gpointer data)
ctxt->book = book;
ctxt->query = query;
if (uses_book) {
- ctxt->cards = NULL;
+ ctxt->contacts = NULL;
e_contact_do_print(book, ctxt->query, ctxt);
}
else if (uses_list) {
- ctxt->cards = card_list;
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
+ ctxt->contacts = contact_list;
+ complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, ctxt);
}
else {
- ctxt->cards = g_list_append(NULL, card);
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
+ ctxt->contacts = g_list_append(NULL, contact);
+ complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, ctxt);
}
gtk_widget_destroy (dialog);
break;
@@ -1119,28 +964,28 @@ e_contact_print_response(GtkWidget *dialog, gint response_id, gpointer data)
ctxt->book = book;
ctxt->query = g_strdup(query);
if (uses_book) {
- ctxt->cards = NULL;
+ ctxt->contacts = NULL;
g_object_ref(book);
e_contact_do_print(book, ctxt->query, ctxt);
}
else if (uses_list) {
- ctxt->cards = g_list_copy (card_list);
- g_list_foreach (ctxt->cards, (GFunc)g_object_ref, NULL);
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
+ ctxt->contacts = g_list_copy (contact_list);
+ g_list_foreach (ctxt->contacts, (GFunc)g_object_ref, NULL);
+ complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, ctxt);
}
else {
- ctxt->cards = g_list_append(NULL, card);
- g_object_ref(card);
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
+ ctxt->contacts = g_list_append(NULL, contact);
+ g_object_ref(contact);
+ complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, ctxt);
}
break;
case GNOME_PRINT_DIALOG_RESPONSE_CANCEL:
if (uses_book)
g_object_unref(book);
else if (uses_list)
- e_free_object_list (card_list);
+ e_free_object_list (contact_list);
else
- g_object_unref(card);
+ g_object_unref(contact);
g_free(query);
gtk_widget_destroy (dialog);
g_free(style);
@@ -1155,7 +1000,7 @@ e_contact_print_dialog_new(EBook *book, char *query)
GtkWidget *dialog;
- dialog = gnome_print_dialog_new(NULL, _("Print cards"), GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES);
+ dialog = gnome_print_dialog_new(NULL, _("Print contacts"), GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES);
gnome_print_dialog_construct_range_any(GNOME_PRINT_DIALOG(dialog), GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_SELECTION,
NULL, NULL, NULL);
@@ -1211,20 +1056,20 @@ e_contact_print_preview(EBook *book, char *query)
#endif
ctxt->book = book;
ctxt->query = g_strdup(query);
- ctxt->cards = NULL;
+ ctxt->contacts = NULL;
g_object_ref(book);
e_contact_do_print(book, ctxt->query, ctxt);
}
GtkWidget *
-e_contact_print_card_dialog_new(ECard *card)
+e_contact_print_contact_dialog_new(EContact *contact)
{
GtkWidget *dialog;
- dialog = gnome_print_dialog_new(NULL, _("Print card"), GNOME_PRINT_DIALOG_COPIES);
+ dialog = gnome_print_dialog_new(NULL, _("Print contact"), GNOME_PRINT_DIALOG_COPIES);
- card = e_card_duplicate(card);
- g_object_set_data(G_OBJECT(dialog), "card", card);
+ contact = e_contact_duplicate(contact);
+ g_object_set_data(G_OBJECT(dialog), "contact", contact);
g_object_set_data(G_OBJECT(dialog), "uses_list", GINT_TO_POINTER (FALSE));
g_object_set_data(G_OBJECT(dialog), "uses_book", GINT_TO_POINTER (FALSE));
g_signal_connect(dialog,
@@ -1235,22 +1080,22 @@ e_contact_print_card_dialog_new(ECard *card)
}
GtkWidget *
-e_contact_print_card_list_dialog_new(GList *list)
+e_contact_print_contact_list_dialog_new(GList *list)
{
GtkWidget *dialog;
- ECard *card;
GList *copied_list;
+ GList *l;
if (list == NULL)
return NULL;
copied_list = g_list_copy (list);
- g_list_foreach (copied_list, (GFunc)g_object_ref, NULL);
+ for (l = copied_list; l; l = l->next)
+ l->data = e_contact_duplicate (E_CONTACT (l->data));
- dialog = gnome_print_dialog_new(NULL, _("Print card"), GNOME_PRINT_DIALOG_COPIES);
+ dialog = gnome_print_dialog_new(NULL, _("Print contact"), GNOME_PRINT_DIALOG_COPIES);
- card = e_card_duplicate(list->data);
- g_object_set_data(G_OBJECT(dialog), "card_list", copied_list);
+ g_object_set_data(G_OBJECT(dialog), "contact_list", copied_list);
g_object_set_data(G_OBJECT(dialog), "uses_list", GINT_TO_POINTER (TRUE));
g_object_set_data(G_OBJECT(dialog), "uses_book", GINT_TO_POINTER (FALSE));
g_signal_connect(dialog,
diff --git a/addressbook/printing/e-contact-print.h b/addressbook/printing/e-contact-print.h
index 12f13f4573..8c2fbb6acb 100644
--- a/addressbook/printing/e-contact-print.h
+++ b/addressbook/printing/e-contact-print.h
@@ -25,12 +25,12 @@
#include <glib.h>
#include <gtk/gtkwidget.h>
#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-card.h>
+#include <addressbook/backend/ebook/e-contact.h>
#include "e-contact-print-types.h"
GtkWidget *e_contact_print_dialog_new(EBook *book, char *query);
void e_contact_print_preview(EBook *book, char *query);
-GtkWidget *e_contact_print_card_dialog_new(ECard *card);
-GtkWidget *e_contact_print_card_list_dialog_new(GList *list);
+GtkWidget *e_contact_print_contact_dialog_new(EContact *card);
+GtkWidget *e_contact_print_contact_list_dialog_new(GList *list);
#endif /* E_CONTACT_PRINT_H */
diff --git a/addressbook/tools/Makefile.am b/addressbook/tools/Makefile.am
index 79a1c746ad..c9e082603e 100644
--- a/addressbook/tools/Makefile.am
+++ b/addressbook/tools/Makefile.am
@@ -1,6 +1,12 @@
+privlibexec_SCRIPTS = \
+ csv2vcard \
+ evolution-addressbook-clean
+
bin_PROGRAMS = \
evolution-addressbook-export
+noinst_PROGRAMS= evolution-addressbook-abuse
+
INCLUDES = \
-DG_LOG_DOMAIN=\"evolution-addressbook-tools\" \
-I$(top_srcdir) \
@@ -23,11 +29,22 @@ evolution_addressbook_export_SOURCES = \
evolution-addressbook-export.h
evolution_addressbook_export_LDADD = \
- $(GNOME_FULL_LIBS) \
$(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/libversit/libversit.la \
$(top_builddir)/e-util/ename/libename.la \
$(top_builddir)/e-util/libeutil.la
+evolution_addressbook_abuse_LDADD = \
+ $(top_builddir)/addressbook/backend/ebook/libebook.la \
+ $(top_builddir)/e-util/ename/libename.la \
+ $(top_builddir)/e-util/libeutil.la
+
+EXTRA_DIST = $(privlibexec_SCRIPTS) \
+ evolution-addressbook-clean.in
+
+CLEANFILES= evolution-addressbook-clean
+
+evolution-addressbook-clean: evolution-addressbook-clean.in Makefile
+## Use sed and then mv to avoid problems if the user interrupts.
+ sed -e 's?\@EVOLUTION_TOOLSDIR\@?$(privlibexecdir)?g' \
+ < $(srcdir)/evolution-addressbook-clean.in > evolution-addressbook-clean.tmp \
+ && mv evolution-addressbook-clean.tmp evolution-addressbook-clean
diff --git a/addressbook/tools/csv2vcard b/addressbook/tools/csv2vcard
new file mode 100755
index 0000000000..b968fbd9c3
--- /dev/null
+++ b/addressbook/tools/csv2vcard
@@ -0,0 +1,236 @@
+#!/usr/bin/perl -w
+#
+# cvs2vcard - Script to convert Outlook CSV files into VCard files
+# suitable to be imported into Evolution.
+#
+# Copyright (C) 2001 Ximian, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Author: Michael MacDonald <mjmac@ximian.com>
+#
+
+use strict;
+use diagnostics;
+use Text::ParseWords;
+
+sub usage
+{
+ print STDERR << "--EndOfUsage";
+
+Takes a CSV-formatted list of contacts from Outlook and attempts to
+convert it into a list of VCards suitable for import into Evolution.
+
+Usage: $0 [infile outfile]
+
+--EndOfUsage
+
+ exit;
+}
+
+sub is_recognized_format
+{
+ my $line = shift;
+
+ # Making some assumptions here... Prolly OK.
+ return $line =~ /(First Name|Middle Name|Last Name)/;
+}
+
+sub map_columns
+{
+ my $line = shift;
+
+ my @names = parse_line(',', 0, $line);
+
+ my $ctr = 0;
+ my %fieldmap = map { $_ => $ctr++ } @names;
+
+ return %fieldmap;
+}
+
+sub build_vcard_attr_from_def
+{
+ my ($def, $fields, $map) = @_;
+
+ # Valid chars for lookup (from Outlook CSV) are
+ # A-Za-z0-9_-'/
+ # Valid chars for formatting of attr are
+ # \s,|
+ my @lookup = map { s/=0A$//; s/[^\w\s\-'\/]//; $_; } split /[\s,]*\|[\s,]*/, $def;
+
+ foreach my $el (@lookup) {
+ unless (defined($map->{ $el })) {
+ print STDERR "$el is undefined\n";
+ next;
+ }
+ if (defined($fields->[$map->{ $el }])) {
+ unless ($fields->[$map->{ $el }] =~ /(^$|0\/0\/00)/) {
+ $def =~ s/$el/$fields->[$map->{ $el }]/;
+ } else {
+ $def =~ s/((?<=\|)\s*)?$el(\s*?(?=\|))?(=0A)?,?//;
+ }
+ } else {
+ $def =~ s/((?<=\|)\s*)?$el(\s*?(?=\|))?(=0A)?,?//;
+ }
+ }
+ # Get rid of field delimiters
+ $def =~ s/\|//g;
+ # Snip off any trailing semicolons or whitespace
+ $def =~ s/[\s;]*$//;
+
+ return $def;
+}
+
+sub build_vcard_from_line {
+ my ($line, %map) = @_;
+ my %vcard;
+
+ my @fields = parse_line(',', 0, $line);
+
+ my %vcard_def = ( FN => 'Title |First Name |Middle Name |Last Name |Suffix',
+ N => 'Last Name| Suffix|;First Name|;Middle Name|;Title',
+ 'ADR;WORK' => 'PO Box|;Business Street 2|;Business Street|;Business City|;Business State|;Business Postal Code|;Business Country',
+ 'LABEL;QUOTED-PRINTABLE;WORK' => 'PO Box |Business Street=0A|Business Street 2=0A|Business City,| Business State| Business Postal Code=0A|Business Country',
+ 'TEL;WORK;VOICE' => 'Business Phone',
+ 'TEL;WORK;VOICE2' => 'Business Phone 2',
+ 'TEL;WORK;FAX' => 'Business Fax',
+ 'TEL;WORK;COMPANY' => 'Company Main Phone',
+ 'ADR;HOME' => ';Home Street 2|;Home Street|;Home City|;Home State|;Home Postal Code|;Home Country',
+ 'LABEL;QUOTED-PRINTABLE;HOME' => 'Home Street=0A|Home Street 2=0A|Home City,| Home State| Home Postal Code=0A|Home Country',
+ 'TEL;HOME;VOICE' => 'Home Phone',
+ 'TEL;HOME;VOICE2' => 'Home Phone 2',
+ 'TEL;HOME;FAX' => 'Home Fax',
+ 'ADR;POSTAL' => ';Other Street 2|;Other Street|;Other City|;Other State|;Other Postal Code|;Other Country',
+ 'LABEL;QUOTED-PRINTABLE;POSTAL' => 'Other Street=0A|Other Street 2=0A|Other City,| Other State| Other Postal Code=0A|Other Country',
+ 'TEL;VOICE' => 'Other Phone',
+ 'TEL;FAX' => 'Other Fax',
+ 'TEL;CELL' => 'Mobile Phone',
+ 'TEL;CAR' => 'Car Phone',
+ 'TEL;PAGER' => 'Pager',
+ 'TEL;PREF' => 'Primary Phone',
+ 'TEL;ISDN' => 'ISDN',
+ 'TEL;X-EVOLUTION-CALLBACK' => 'Callback',
+ 'TEL;X-EVOLUTION-TTYTDD' => 'TTY/TDD Phone',
+ 'TEL;X-EVOLUTION-TELEX' => 'Telex',
+ 'TEL;X-EVOLUTION-RADIO' => 'Radio Phone',
+ 'EMAIL;INTERNET' => 'E-mail Address',
+ 'EMAIL;INTERNET2' => 'E-mail 2 Address',
+ 'EMAIL;INTERNET3' => 'E-mail 3 Address',
+ ORG => 'Company|;Department',
+ TITLE => 'Job Title',
+ ROLE => 'Profession',
+ 'X-EVOLUTION-ASSISTANT' => "Assistant's Name",
+ 'TEL;X-EVOLUTION-ASSISTANT' => "Assistant's Phone",
+ 'X-EVOLUTION-SPOUSE' => 'Spouse',
+ 'X-EVOLUTION-ANNIVERSARY' => 'Anniversary',
+ 'X-EVOLUTION-MANAGER' => "Manager's Name",
+ 'X-EVOLUTION-OFFICE' => 'Office Location',
+ BDAY => 'Birthday',
+ NOTE => 'Notes',
+ FBURL => 'Internet Free Busy',
+ URL => 'Web Page',
+ );
+
+ foreach my $key (keys(%vcard_def)) {
+ my $attr = build_vcard_attr_from_def($vcard_def{ $key }, \@fields, \%map);
+ if (defined($attr)) {
+ $vcard{ $key } = $attr unless ($attr =~ /^$/);
+ }
+ }
+
+ return %vcard;
+}
+
+sub print_vcard_to_fh
+{
+ my ($fh, %vcard) = @_;
+
+ print $fh "BEGIN:VCARD\n";
+ foreach my $key (keys(%vcard)) {
+ # Dirty hack because Evolution's vcard stores multiple email addrs
+ # with same sttribute, hence key collision. Bleah.
+ # Ugh! Same deal for multiple phones... (eg. bus. phone)
+ #
+ # And finally, while we're special-casing... Outlook exports dates
+ # differently, so munge 'em if we find 'em.
+ if ($key =~ /EMAIL;INTERNET/o) {
+ (my $temp = $key) =~ s/\d$//;
+ print $fh "$temp:$vcard{ $key }\n";
+ } elsif ($key =~ /TEL;(HOME|WORK)/o) {
+ (my $temp = $key) =~ s/\d$//;
+ print $fh "$temp:$vcard{ $key }\n";
+ } elsif ($key =~ /(BDAY|X\-EVOLUTION\-ANNIVERSARY)/o) {
+ my $temp = $vcard{ $key };
+ if ($temp =~ /(\d\d)\/(\d\d)\/(\d\d)/) {
+ # Y2k !! MS Didn't learn anything.
+ # Hope no one was born before 1915
+ if ((1900 + $3) < 1915) {
+ print $fh "$key:20$3-$1-$2\n";
+ } else {
+ print $fh "$key:19$3-$1-$2\n";
+ }
+ } else {
+ # Something's funky... Just delete the attribute
+ print STDERR "Couldn't figure out what to do with $key:$vcard{ $key }\n";
+ delete($vcard{ $key });
+ }
+ } else {
+ print $fh "$key:$vcard{ $key }\n";
+ }
+ }
+ print $fh "END:VCARD\n\n";
+}
+
+my $in = $ARGV[0];
+my $out = $ARGV[1];
+
+usage() unless(defined($in) && defined($out));
+
+open (IN, $in)
+ or die "Can't open($in): $!\n";
+
+open (OUT, ">$out")
+ or die "Can't open($out): $!\n";
+
+my $linectr = 0;
+my %map;
+
+while (my $line = <IN>) {
+ $line =~ s/\r//g;
+ $line =~ s/\n$//;
+ if ($linectr == 0) {
+ $linectr++;
+ usage() unless is_recognized_format($line);
+ %map = map_columns($line);
+ #if ($line =~ /\r\n$/) {
+ # print STDERR "Apparenlty found DOS-style EOL indicators...\n";
+ $/ = "\r\n";
+ #}
+ } else {
+ $linectr++;
+ while ($line =~ /^(("([^"]|\n|"")*")?,)*"([^"]|\n|"")*$/) {
+ my $temp = $line;
+ $line = <IN>;
+ $line =~ s/\r//g;
+ $line =~ s/\n$//;
+ $line = "$temp $line";
+ }
+ my %vcard = build_vcard_from_line($line, %map);
+ print_vcard_to_fh(\*OUT, %vcard);
+ }
+}
+
+close(IN);
+close(OUT);
diff --git a/addressbook/tools/evolution-addressbook-abuse.c b/addressbook/tools/evolution-addressbook-abuse.c
new file mode 100644
index 0000000000..7801ed7e9d
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-abuse.c
@@ -0,0 +1,127 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <config.h>
+
+#include <bonobo-activation/bonobo-activation.h>
+#include <bonobo/bonobo-main.h>
+
+#include <backend/ebook/e-book-async.h>
+#include <gnome.h>
+
+static int contacts_to_add_total = 1000;
+static int contacts_to_add = 50;
+static int call_count = 0;
+
+static gchar *
+make_random_string (void)
+{
+ const gchar *elements = " abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ gint len = strlen (elements);
+ gint i, N = 5 + (random () % 10);
+ gchar *str = g_malloc (N+1);
+
+ for (i = 0; i < N; ++i) {
+ str[i] = elements[random () % len];
+ }
+ str[i] = '\0';
+
+ return str;
+}
+
+static gchar *
+make_random_vcard (void)
+{
+ gchar *fa = make_random_string ();
+ gchar *name = make_random_string ();
+ gchar *email = make_random_string ();
+ gchar *org = make_random_string ();
+
+ gchar *vcard;
+
+ vcard = g_strdup_printf ("BEGIN:VCARD\n"
+ "X-EVOLUTION-FILE-AS:%s\n"
+ "N:%s\n"
+ "EMAIL;INTERNET:%s\n"
+ "ORG:%s\n"
+ "END:VCARD",
+ fa, name, email, org);
+ g_free (fa);
+ g_free (name);
+ g_free (email);
+ g_free (org);
+
+ return vcard;
+}
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+static void
+add_cb (EBook *book, EBookStatus status, const char *id, gpointer closure)
+{
+ switch (status) {
+ case E_BOOK_ERROR_OK:
+ --contacts_to_add_total;
+ g_message ("succesful add! (%d remaining)", contacts_to_add_total);
+ if (contacts_to_add_total <= 0)
+ g_main_loop_quit (NULL);
+ break;
+ default:
+ g_message ("something went wrong...");
+ g_main_loop_quit (NULL);
+ break;
+ }
+}
+
+static void
+use_addressbook (EBook *book, EBookStatus status, gpointer closure)
+{
+ gint i;
+
+ if (book == NULL || status != E_BOOK_ERROR_OK)
+ g_error (_("Error loading default addressbook."));
+
+ for (i = 0; i < contacts_to_add; ++i) {
+ gchar *vcard = make_random_vcard ();
+ EContact *contact = e_contact_new_from_vcard (vcard);
+ g_message ("adding %d", i);
+ e_book_async_add_contact (book, contact, add_cb, NULL);
+ g_free (vcard);
+ g_object_unref (contact);
+ }
+
+ g_object_unref (book);
+}
+
+static gint
+abuse_timeout (gpointer foo)
+{
+ e_book_async_get_default_addressbook (use_addressbook, NULL);
+
+ ++call_count;
+ g_message ("timeout!");
+ return call_count < contacts_to_add_total / contacts_to_add;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (getenv ("ABUSE_THE_WOMBAT") == NULL) {
+ g_print ("You probably don't want to use this program.\n"
+ "It isn't very nice.\n");
+ exit(0);
+ }
+
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ textdomain (GETTEXT_PACKAGE);
+
+ gnome_program_init ("evolution-addressbook-abuse", VERSION,
+ LIBGNOMEUI_MODULE, argc, argv,
+ GNOME_PROGRAM_STANDARD_PROPERTIES,
+ NULL);
+
+ g_timeout_add (20, abuse_timeout, NULL);
+
+ bonobo_main ();
+
+ return 0;
+}
diff --git a/addressbook/tools/evolution-addressbook-clean.in b/addressbook/tools/evolution-addressbook-clean.in
new file mode 100644
index 0000000000..b7ee7ba167
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-clean.in
@@ -0,0 +1,24 @@
+#! /usr/bin/perl -w
+
+sub do_system
+{
+ my ($command) = @_;
+ system ($command);
+ if ($? != 0) {
+ die "Command failed: $command";
+ }
+}
+
+$filename = `@EVOLUTION_TOOLSDIR@/evolution-addressbook-export`;
+if ($? != 0) {
+ $! = $?;
+ die $!;
+}
+
+$HOME = $ENV{"HOME"};
+
+system ("@EVOLUTION_TOOLSDIR@/killev");
+do_system ("/bin/mv ${HOME}/evolution/local/Contacts/addressbook.db ${HOME}/evolution/local/Contacts/addressbook-backup.db");
+do_system ("@EVOLUTION_TOOLSDIR@/evolution-addressbook-import --input-file $filename");
+do_system ("/bin/rm $filename");
+
diff --git a/addressbook/tools/evolution-addressbook-import.c b/addressbook/tools/evolution-addressbook-import.c
new file mode 100644
index 0000000000..28871efd96
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-import.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <config.h>
+
+#include <bonobo-activation/bonobo-activation.h>
+#include <bonobo/bonobo-main.h>
+#include <backend/ebook/e-book-async.h>
+#include <gnome.h>
+
+static int exec_ref_count = 0;
+
+static void
+ref_executable (void)
+{
+ exec_ref_count ++;
+}
+
+static void
+unref_executable (void)
+{
+ exec_ref_count --;
+ if (exec_ref_count == 0)
+ g_main_loop_quit (0);
+}
+
+static void
+add_cb (EBook *book, EBookStatus status, const char *id, gpointer closure)
+{
+ switch (status) {
+ case E_BOOK_ERROR_OK:
+ unref_executable ();
+ break;
+ default:
+ g_main_loop_quit (NULL);
+ break;
+ }
+}
+
+static void
+use_addressbook (EBook *book, gpointer closure)
+{
+ GList *cards, *list;
+ char *filename = closure;
+
+ if (book == NULL)
+ g_error (_("Error loading default addressbook."));
+
+ cards = e_card_load_cards_from_file (filename);
+
+ ref_executable ();
+
+ for (list = cards; list; list = list->next) {
+ ref_executable ();
+ e_book_add_card (book, list->data, add_cb, closure);
+ }
+ sync();
+
+ unref_executable ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *filename = NULL;
+
+ struct poptOption options[] = {
+ { "input-file", '\0', POPT_ARG_STRING, &filename, 0, N_("Input File"), NULL },
+ POPT_AUTOHELP
+ { NULL, '\0', 0, NULL, 0, NULL, NULL }
+ };
+
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ textdomain (GETTEXT_PACKAGE);
+
+ gnome_program_init ("evolution-addressbook-import", VERSION,
+ LIBGNOMEUI_MODULE, argc, argv,
+ GNOME_PROGRAM_STANDARD_PROPERTIES,
+ GNOME_PARAM_POPT_TABLE, options,
+ NULL);
+
+ if (filename == NULL) {
+ g_error (_("No filename provided."));
+ }
+
+ e_book_async_get_default_addressbook (use_addressbook, filename);
+
+ bonobo_main ();
+
+ return 0;
+}
diff --git a/addressbook/util/.cvsignore b/addressbook/util/.cvsignore
new file mode 100644
index 0000000000..6205c6f3ab
--- /dev/null
+++ b/addressbook/util/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+Makefile.in
+eab-marshal.c
+eab-marshal.h
diff --git a/addressbook/util/Makefile.am b/addressbook/util/Makefile.am
new file mode 100644
index 0000000000..51b6e7fc28
--- /dev/null
+++ b/addressbook/util/Makefile.am
@@ -0,0 +1,41 @@
+INCLUDES = \
+ -DPREFIX=\"$(prefix)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\" \
+ -DG_LOG_DOMAIN=\"EBook\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/camel \
+ -I$(top_srcdir)/addressbook/backend \
+ -I$(top_srcdir)/addressbook/ename \
+ -I$(top_builddir)/addressbook/backend \
+ -I$(top_builddir)/addressbook/ename \
+ -I$(top_builddir)/shell \
+ -I$(top_srcdir)/shell \
+ -DG_DISABLE_DEPRECATED \
+ -DLIBGNOME_DISABLE_DEPRECATED \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+
+noinst_LTLIBRARIES = libeabutil.la
+
+libeabutil_la_SOURCES = \
+ eab-marshal.c \
+ eab-destination.c \
+ eab-destination.h \
+ eab-book-util.c \
+ eab-book-util.h
+
+libeabutil_la_LIBADD = \
+ $(top_builddir)/addressbook/backend/ebook/libebook.la \
+ $(top_builddir)/camel/libcamel.la \
+ $(top_builddir)/e-util/ename/libename.la \
+ $(top_builddir)/e-util/libeutil.la
+
+MARSHAL_GENERATED = eab-marshal.c eab-marshal.h
+@EVO_MARSHAL_RULE@
+
+BUILT_SOURCES = $(MARSHAL_GENERATED)
+CLEANFILES = $(BUILT_SOURCES)
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
diff --git a/addressbook/util/eab-book-util.c b/addressbook/util/eab-book-util.c
new file mode 100644
index 0000000000..2c80d6f8a1
--- /dev/null
+++ b/addressbook/util/eab-book-util.c
@@ -0,0 +1,293 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * eab-util.c
+ *
+ * Copyright (C) 2001-2003 Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#include <config.h>
+#include "eab-book-util.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <e-util/e-config-listener.h>
+
+EConfigListener *
+eab_get_config_database ()
+{
+ static EConfigListener *config_db;
+
+ if (config_db == NULL)
+ config_db = e_config_listener_new ();
+
+ return config_db;
+}
+
+/*
+ *
+ * Specialized Queries
+ *
+ */
+
+guint
+eab_name_and_email_query (EBook *book,
+ const gchar *name,
+ const gchar *email,
+ EBookContactsCallback cb,
+ gpointer closure)
+{
+ gchar *email_query=NULL, *name_query=NULL, *query;
+ guint tag;
+
+ g_return_val_if_fail (book && E_IS_BOOK (book), 0);
+ g_return_val_if_fail (cb != NULL, 0);
+
+ if (name && !*name)
+ name = NULL;
+ if (email && !*email)
+ email = NULL;
+
+ if (name == NULL && email == NULL)
+ return 0;
+
+ /* Build our e-mail query.
+ * We only query against the username part of the address, to avoid not matching
+ * fred@foo.com and fred@mail.foo.com. While their may be namespace collisions
+ * in the usernames of everyone out there, it shouldn't be that bad. (Famous last words.)
+ */
+ if (email) {
+ const gchar *t = email;
+ while (*t && *t != '@')
+ ++t;
+ if (*t == '@') {
+ email_query = g_strdup_printf ("(beginswith \"email\" \"%.*s@\")", t-email, email);
+
+ } else {
+ email_query = g_strdup_printf ("(beginswith \"email\" \"%s\")", email);
+ }
+ }
+
+ /* Build our name query.
+ * We only do name-query stuff if we don't have an e-mail address. Our basic assumption
+ * is that the username part of the email is good enough to keep the amount of stuff returned
+ * in the query relatively small.
+ */
+ if (name && !email)
+ name_query = g_strdup_printf ("(or (beginswith \"file_as\" \"%s\") (beginswith \"full_name\" \"%s\"))", name, name);
+
+ /* Assemble our e-mail & name queries */
+ if (email_query && name_query) {
+ query = g_strdup_printf ("(and %s %s)", email_query, name_query);
+ } else if (email_query) {
+ query = email_query;
+ email_query = NULL;
+ } else if (name_query) {
+ query = name_query;
+ name_query = NULL;
+ } else
+ return 0;
+
+ tag = e_book_async_get_contacts (book, query, cb, closure);
+
+ g_free (email_query);
+ g_free (name_query);
+ g_free (query);
+
+ return tag;
+}
+
+/*
+ * Simple nickname query
+ */
+guint
+eab_nickname_query (EBook *book,
+ const char *nickname,
+ EBookContactsCallback cb,
+ gpointer closure)
+{
+ gchar *query;
+ guint retval;
+
+ g_return_val_if_fail (E_IS_BOOK (book), 0);
+ g_return_val_if_fail (nickname != NULL, 0);
+
+ /* The empty-string case shouldn't generate a warning. */
+ if (! *nickname)
+ return 0;
+
+ query = g_strdup_printf ("(is \"nickname\" \"%s\")", nickname);
+
+ retval = e_book_async_get_contacts (book, query, cb, closure);
+
+ g_free (query);
+
+ return retval;
+}
+
+GList*
+eab_contact_list_from_string (const char *str)
+{
+ GList *contacts = NULL;
+ GString *gstr = g_string_new ("");
+ char *p = (char*)str;
+ char *q;
+ char *blank_line;
+
+ while (*p) {
+ if (*p != '\r') g_string_append_c (gstr, *p);
+
+ p++;
+ }
+
+ p = g_string_free (gstr, FALSE);
+ q = p;
+ do {
+ char *temp;
+
+ blank_line = strstr (q, "\n\n");
+ if (blank_line) {
+ temp = g_strndup (q, blank_line - q);
+ }
+ else {
+ temp = g_strdup (q);
+ }
+
+ contacts = g_list_append (contacts, e_contact_new_from_vcard (temp));
+
+ g_free (temp);
+
+ if (blank_line)
+ q = blank_line + 2;
+ else
+ q = NULL;
+ } while (blank_line);
+
+ g_free (p);
+
+ return contacts;
+}
+
+char*
+eab_contact_list_to_string (GList *contacts)
+{
+ GString *str = g_string_new ("");
+ GList *l;
+
+ for (l = contacts; l; l = l->next) {
+ EContact *contact = l->data;
+ char *vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+
+ g_string_append (str, vcard_str);
+ if (l->next)
+ g_string_append (str, "\r\n");
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+#if notyet
+/*
+ * Convenience routine to check for addresses in the local address book.
+ */
+
+typedef struct _HaveAddressInfo HaveAddressInfo;
+struct _HaveAddressInfo {
+ gchar *email;
+ EBookHaveAddressCallback cb;
+ gpointer closure;
+};
+
+static void
+have_address_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *contacts, gpointer closure)
+{
+ HaveAddressInfo *info = (HaveAddressInfo *) closure;
+
+ info->cb (book,
+ info->email,
+ contacts && (status == E_BOOK_ERROR_OK) ? E_CONTACT (contacts->data) : NULL,
+ info->closure);
+
+ g_free (info->email);
+ g_free (info);
+}
+
+static void
+have_address_book_open_cb (EBook *book, gpointer closure)
+{
+ HaveAddressInfo *info = (HaveAddressInfo *) closure;
+
+ if (book) {
+
+ e_book_name_and_email_query (book, NULL, info->email, have_address_query_cb, info);
+
+ } else {
+
+ info->cb (NULL, info->email, NULL, info->closure);
+
+ g_free (info->email);
+ g_free (info);
+
+ }
+}
+
+void
+eab_query_address_default (const gchar *email,
+ EABHaveAddressCallback cb,
+ gpointer closure)
+{
+ HaveAddressInfo *info;
+
+ g_return_if_fail (email != NULL);
+ g_return_if_fail (cb != NULL);
+
+ info = g_new0 (HaveAddressInfo, 1);
+ info->email = g_strdup (email);
+ info->cb = cb;
+ info->closure = closure;
+
+ e_book_use_default_book (have_address_book_open_cb, info);
+}
+#endif
+
+/* bad place for this i know. */
+int
+e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len)
+{
+ gchar *s1 = g_utf8_casefold(str1, len);
+ gchar *s2 = g_utf8_casefold(str2, len);
+ int rv;
+
+ rv = g_utf8_collate (s1, s2);
+
+ g_free (s1);
+ g_free (s2);
+
+ return rv;
+}
+
+int
+e_utf8_casefold_collate (const gchar *str1, const gchar *str2)
+{
+ return e_utf8_casefold_collate_len (str1, str2, -1);
+}
diff --git a/addressbook/util/eab-book-util.h b/addressbook/util/eab-book-util.h
new file mode 100644
index 0000000000..be5451b795
--- /dev/null
+++ b/addressbook/util/eab-book-util.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * e-book-util.h
+ *
+ * Copyright (C) 2001-2003 Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#ifndef __EAB_UTIL_H__
+#define __EAB_UTIL_H__
+
+#include "ebook/e-book-async.h"
+#include "e-util/e-config-listener.h"
+#include <bonobo/bonobo-object.h>
+#include <bonobo/bonobo-moniker-util.h>
+
+G_BEGIN_DECLS
+
+typedef void (*EABHaveAddressCallback) (EBook *book, const gchar *addr, EContact *contact, gpointer closure);
+
+/* config database interface. */
+EConfigListener *eab_get_config_database (void);
+
+/* Specialized Name/Email Queries */
+guint eab_name_and_email_query (EBook *book,
+ const char *name,
+ const char *email,
+ EBookContactsCallback cb,
+ gpointer closure);
+guint eab_nickname_query (EBook *book,
+ const char *nickname,
+ EBookContactsCallback cb,
+ gpointer closure);
+
+GList *eab_contact_list_from_string (const char *str);
+char *eab_contact_list_to_string (GList *contacts);
+
+/* Returns the EContact associated to email in the callback,
+ or NULL if no match is found in the default address book. */
+void eab_query_address_default (const gchar *email,
+ EABHaveAddressCallback cb,
+ gpointer closure);
+
+int e_utf8_casefold_collate_len (const gchar *str1, const gchar *str2, int len);
+int e_utf8_casefold_collate (const gchar *str1, const gchar *str2);
+
+G_END_DECLS
+
+#endif /* __EAB_UTIL_H__ */
+
diff --git a/addressbook/util/eab-destination.c b/addressbook/util/eab-destination.c
new file mode 100644
index 0000000000..d83ad8563a
--- /dev/null
+++ b/addressbook/util/eab-destination.c
@@ -0,0 +1,1569 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * eab-destination.c
+ *
+ * Copyright (C) 2001-2003 Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#include <config.h>
+#include "eab-destination.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "ebook/e-book.h"
+#include "eab-marshal.h"
+#include "eab-book-util.h"
+#include <gal/widgets/e-unicode.h>
+
+#include <glib.h>
+#include <libxml/xmlmemory.h>
+#include <camel/camel-internet-address.h>
+
+#define d(x)
+
+enum {
+ CHANGED,
+ CONTACT_LOADED,
+ LAST_SIGNAL
+};
+
+guint eab_destination_signals[LAST_SIGNAL] = { 0 };
+
+struct _EABDestinationPrivate {
+ gchar *raw;
+
+ gchar *book_uri;
+ gchar *uid;
+ EContact *contact;
+ gint email_num;
+
+ gchar *name;
+ gchar *email;
+ gchar *addr;
+ gchar *textrep;
+
+ GList *list_dests;
+
+ guint html_mail_override : 1;
+ guint wants_html_mail : 1;
+
+ guint show_addresses : 1;
+
+ guint contact_loaded : 1;
+ guint cannot_load : 1;
+ guint auto_recipient : 1;
+ guint pending_contact_load;
+
+ guint pending_change : 1;
+
+ EBook *book;
+
+ gint freeze_count;
+};
+
+static void eab_destination_clear_contact (EABDestination *);
+static void eab_destination_clear_strings (EABDestination *);
+
+/* the following prototypes were in e-destination.h, but weren't used
+ by anything in evolution... let's make them private for now. */
+static gboolean eab_destination_is_valid (const EABDestination *);
+static void eab_destination_set_contact_uid (EABDestination *, const gchar *uid, gint email_num);
+static void eab_destination_set_book_uri (EABDestination *, const gchar *uri);
+static gboolean eab_destination_from_contact (const EABDestination *);
+static const gchar *eab_destination_get_book_uri (const EABDestination *);
+static const gchar *eab_destination_get_contact_uid (const EABDestination *);
+static xmlNodePtr eab_destination_xml_encode (const EABDestination *dest);
+static gboolean eab_destination_xml_decode (EABDestination *dest, xmlNodePtr node);
+
+static GObjectClass *parent_class;
+
+static void
+eab_destination_dispose (GObject *obj)
+{
+ EABDestination *dest = EAB_DESTINATION (obj);
+
+ if (dest->priv) {
+ eab_destination_clear (dest);
+
+ if (dest->priv->book)
+ g_object_unref (dest->priv->book);
+
+ g_free (dest->priv);
+ dest->priv = NULL;
+ }
+
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ (* G_OBJECT_CLASS (parent_class)->dispose) (obj);
+}
+
+static void
+eab_destination_class_init (EABDestinationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+ object_class->dispose = eab_destination_dispose;
+
+ eab_destination_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EABDestinationClass, changed),
+ NULL, NULL,
+ eab_marshal_NONE__NONE,
+ G_TYPE_NONE, 0);
+
+ eab_destination_signals[CONTACT_LOADED] =
+ g_signal_new ("contact_loaded",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EABDestinationClass, contact_loaded),
+ NULL, NULL,
+ eab_marshal_NONE__NONE,
+ G_TYPE_NONE, 0);
+}
+
+static void
+eab_destination_init (EABDestination *dest)
+{
+ dest->priv = g_new0 (struct _EABDestinationPrivate, 1);
+
+ dest->priv->cannot_load = FALSE;
+ dest->priv->auto_recipient = FALSE;
+ dest->priv->pending_contact_load = 0;
+}
+
+GType
+eab_destination_get_type (void)
+{
+ static GType dest_type = 0;
+
+ if (!dest_type) {
+ GTypeInfo dest_info = {
+ sizeof (EABDestinationClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) eab_destination_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EABDestination),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) eab_destination_init
+ };
+
+ dest_type = g_type_register_static (G_TYPE_OBJECT, "EABDestination", &dest_info, 0);
+ }
+
+ return dest_type;
+}
+
+EABDestination *
+eab_destination_new (void)
+{
+ return g_object_new (EAB_TYPE_DESTINATION, NULL);
+}
+
+static void
+eab_destination_freeze (EABDestination *dest)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+ g_return_if_fail (dest->priv->freeze_count >= 0);
+
+ dest->priv->freeze_count++;
+}
+
+static void
+eab_destination_thaw (EABDestination *dest)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+ g_return_if_fail (dest->priv->freeze_count > 0);
+
+ dest->priv->freeze_count--;
+ if (dest->priv->freeze_count == 0 && dest->priv->pending_change)
+ eab_destination_changed (dest);
+}
+
+void
+eab_destination_changed (EABDestination *dest)
+{
+ if (dest->priv->freeze_count == 0) {
+ g_signal_emit (dest, eab_destination_signals[CHANGED], 0);
+ dest->priv->pending_change = FALSE;
+ dest->priv->cannot_load = FALSE;
+
+ } else {
+ dest->priv->pending_change = TRUE;
+ }
+}
+
+EABDestination *
+eab_destination_copy (const EABDestination *dest)
+{
+ EABDestination *new_dest;
+ GList *iter;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ new_dest = eab_destination_new ();
+
+ new_dest->priv->book_uri = g_strdup (dest->priv->book_uri);
+ new_dest->priv->uid = g_strdup (dest->priv->uid);
+ new_dest->priv->name = g_strdup (dest->priv->name);
+ new_dest->priv->email = g_strdup (dest->priv->email);
+ new_dest->priv->addr = g_strdup (dest->priv->addr);
+ new_dest->priv->email_num = dest->priv->email_num;
+
+ new_dest->priv->contact = dest->priv->contact;
+ if (new_dest->priv->contact)
+ g_object_ref (new_dest->priv->contact);
+
+ new_dest->priv->html_mail_override = dest->priv->html_mail_override;
+ new_dest->priv->wants_html_mail = dest->priv->wants_html_mail;
+
+ for (iter = dest->priv->list_dests; iter != NULL; iter = g_list_next (iter)) {
+ new_dest->priv->list_dests = g_list_append (new_dest->priv->list_dests,
+ eab_destination_copy (EAB_DESTINATION (iter->data)));
+ }
+
+ return new_dest;
+}
+
+static void
+eab_destination_clear_contact (EABDestination *dest)
+{
+ g_free (dest->priv->book_uri);
+ dest->priv->book_uri = NULL;
+ g_free (dest->priv->uid);
+ dest->priv->uid = NULL;
+
+ dest->priv->contact = NULL;
+ dest->priv->email_num = -1;
+
+ g_list_foreach (dest->priv->list_dests, (GFunc) g_object_unref, NULL);
+ g_list_free (dest->priv->list_dests);
+ dest->priv->list_dests = NULL;
+
+ dest->priv->cannot_load = FALSE;
+
+ eab_destination_cancel_contact_load (dest);
+
+ eab_destination_changed (dest);
+}
+
+static void
+eab_destination_clear_strings (EABDestination *dest)
+{
+ g_free (dest->priv->raw);
+ dest->priv->raw = NULL;
+
+ g_free (dest->priv->name);
+ dest->priv->name = NULL;
+
+ g_free (dest->priv->email);
+ dest->priv->email = NULL;
+
+ g_free (dest->priv->addr);
+ dest->priv->addr = NULL;
+
+ g_free (dest->priv->textrep);
+ dest->priv->textrep = NULL;
+
+ eab_destination_changed (dest);
+}
+
+void
+eab_destination_clear (EABDestination *dest)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+
+ eab_destination_freeze (dest);
+
+ eab_destination_clear_contact (dest);
+ eab_destination_clear_strings (dest);
+
+ eab_destination_thaw (dest);
+}
+
+static gboolean
+nonempty (const gchar *s)
+{
+ gunichar c;
+ while (*s) {
+ c = g_utf8_get_char (s);
+ if (!g_unichar_isspace (c))
+ return TRUE;
+ s = g_utf8_next_char (s);
+ }
+ return FALSE;
+}
+
+gboolean
+eab_destination_is_empty (const EABDestination *dest)
+
+{
+ struct _EABDestinationPrivate *p;
+
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), TRUE);
+
+ p = dest->priv;
+
+ return !(p->contact != NULL
+ || (p->book_uri && *p->book_uri)
+ || (p->uid && *p->uid)
+ || (p->raw && nonempty (p->raw))
+ || (p->name && nonempty (p->name))
+ || (p->email && nonempty (p->email))
+ || (p->addr && nonempty (p->addr))
+ || (p->list_dests != NULL));
+}
+
+gboolean
+eab_destination_is_valid (const EABDestination *dest)
+{
+ const char *email;
+
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), FALSE);
+
+ if (eab_destination_from_contact (dest))
+ return TRUE;
+
+ email = eab_destination_get_email (dest);
+
+ /* FIXME: if we really wanted to get fancy here, we could
+ check to make sure that the address was valid according to
+ rfc822's addr-spec grammar. */
+
+ return email && *email && strchr (email, '@');
+}
+
+gboolean
+eab_destination_equal (const EABDestination *a, const EABDestination *b)
+{
+ const struct _EABDestinationPrivate *pa, *pb;
+ const char *na, *nb;
+
+ g_return_val_if_fail (EAB_IS_DESTINATION (a), FALSE);
+ g_return_val_if_fail (EAB_IS_DESTINATION (b), FALSE);
+
+ if (a == b)
+ return TRUE;
+
+ pa = a->priv;
+ pb = b->priv;
+
+ /* Check equality of contacts. */
+ if (pa->contact || pb->contact) {
+ if (! (pa->contact && pb->contact))
+ return FALSE;
+
+ if (pa->contact == pb->contact || !strcmp (e_contact_get_const (pa->contact, E_CONTACT_UID),
+ e_contact_get_const (pb->contact, E_CONTACT_UID)))
+ return TRUE;
+
+ return FALSE;
+ }
+
+ /* Just in case name returns NULL */
+ na = eab_destination_get_name (a);
+ nb = eab_destination_get_name (b);
+ if ((na || nb) && !(na && nb && ! e_utf8_casefold_collate (na, nb)))
+ return FALSE;
+
+ if (!g_ascii_strcasecmp (eab_destination_get_email (a), eab_destination_get_email (b)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void
+eab_destination_set_contact (EABDestination *dest, EContact *contact, gint email_num)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
+
+ if (dest->priv->contact != contact || dest->priv->email_num != email_num) {
+ /* We have to freeze/thaw around these operations so that the 'changed'
+ signals don't cause the EABDestination's internal state to be altered
+ before we can finish setting ->contact && ->email_num. */
+ eab_destination_freeze (dest);
+ eab_destination_clear (dest);
+
+ dest->priv->contact = contact;
+ g_object_ref (dest->priv->contact);
+
+ dest->priv->email_num = email_num;
+
+ eab_destination_changed (dest);
+ eab_destination_thaw (dest);
+ }
+}
+
+static void
+eab_destination_set_book_uri (EABDestination *dest, const gchar *uri)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+ g_return_if_fail (uri != NULL);
+
+ if (dest->priv->book_uri == NULL || strcmp (dest->priv->book_uri, uri)) {
+ g_free (dest->priv->book_uri);
+ dest->priv->book_uri = g_strdup (uri);
+
+ eab_destination_changed (dest);
+ }
+}
+
+void
+eab_destination_set_contact_uid (EABDestination *dest, const gchar *uid, gint email_num)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+ g_return_if_fail (uid != NULL);
+
+ if (dest->priv->uid == NULL
+ || strcmp (dest->priv->uid, uid)
+ || dest->priv->email_num != email_num) {
+
+ g_free (dest->priv->uid);
+ dest->priv->uid = g_strdup (uid);
+ dest->priv->email_num = email_num;
+
+ /* If we already have a contact, remove it unless it's uid matches the one
+ we just set. */
+ if (dest->priv->contact && strcmp (uid,
+ e_contact_get_const (dest->priv->contact, E_CONTACT_UID))) {
+ g_object_unref (dest->priv->contact);
+ dest->priv->contact = NULL;
+ }
+
+ eab_destination_changed (dest);
+ }
+}
+
+void
+eab_destination_set_name (EABDestination *dest, const gchar *name)
+{
+ gboolean changed = FALSE;
+
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+
+ if (name == NULL) {
+ if (dest->priv->name != NULL) {
+ g_free (dest->priv->name);
+ dest->priv->name = NULL;
+ changed = TRUE;
+ }
+ } else if (dest->priv->name == NULL || strcmp (dest->priv->name, name)) {
+ g_free (dest->priv->name);
+ dest->priv->name = g_strdup (name);
+ changed = TRUE;
+ }
+
+ if (changed) {
+ g_free (dest->priv->addr);
+ dest->priv->addr = NULL;
+ g_free (dest->priv->textrep);
+ dest->priv->textrep = NULL;
+ eab_destination_changed (dest);
+ }
+}
+
+void
+eab_destination_set_email (EABDestination *dest, const gchar *email)
+{
+ gboolean changed = FALSE;
+
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+
+ if (email == NULL) {
+ if (dest->priv->email != NULL) {
+ g_free (dest->priv->addr);
+ dest->priv->addr = NULL;
+ changed = TRUE;
+ }
+ } else if (dest->priv->email == NULL || strcmp (dest->priv->email, email)) {
+ g_free (dest->priv->email);
+ dest->priv->email = g_strdup (email);
+ changed = TRUE;
+ }
+
+ if (changed) {
+ g_free (dest->priv->addr);
+ dest->priv->addr = NULL;
+ g_free (dest->priv->textrep);
+ dest->priv->textrep = NULL;
+ eab_destination_changed (dest);
+ }
+}
+
+void
+eab_destination_set_html_mail_pref (EABDestination *dest, gboolean x)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+
+ dest->priv->html_mail_override = TRUE;
+ if (dest->priv->wants_html_mail != x) {
+ dest->priv->wants_html_mail = x;
+ eab_destination_changed (dest);
+ }
+}
+
+gboolean
+eab_destination_contains_contact (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+ return dest->priv->contact != NULL;
+}
+
+gboolean
+eab_destination_from_contact (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+ return dest->priv->contact != NULL || dest->priv->book_uri != NULL || dest->priv->uid != NULL;
+}
+
+gboolean
+eab_destination_is_auto_recipient (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+
+ return dest->priv->auto_recipient;
+}
+
+void
+eab_destination_set_auto_recipient (EABDestination *dest, gboolean value)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+
+ dest->priv->auto_recipient = value;
+}
+
+typedef struct _UseContact UseContact;
+struct _UseContact {
+ EABDestination *dest;
+ EABDestinationContactCallback cb;
+ gpointer closure;
+};
+
+static void
+use_contact_cb (EContact *contact, gpointer closure)
+{
+ UseContact *uc = (UseContact *) closure;
+
+ if (contact != NULL && uc->dest->priv->contact == NULL) {
+ uc->dest->priv->contact = contact;
+ g_object_ref (uc->dest->priv->contact);
+ eab_destination_changed (uc->dest);
+ }
+
+ if (uc->cb) {
+ uc->cb (uc->dest, uc->dest->priv->contact, uc->closure);
+ }
+
+ /* We held a copy of the destination during the callback. */
+ g_object_unref (uc->dest);
+ g_free (uc);
+}
+
+void
+eab_destination_use_contact (EABDestination *dest, EABDestinationContactCallback cb, gpointer closure)
+{
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+
+ if (dest->priv->contact != NULL) {
+ if (cb)
+ cb (dest, dest->priv->contact, closure);
+ } else if (dest->priv->book_uri != NULL && dest->priv->uid != NULL) {
+ UseContact *uc = g_new (UseContact, 1);
+
+ uc->dest = dest;
+ /* Hold a reference to the destination during the callback. */
+ g_object_ref (uc->dest);
+ uc->cb = cb;
+ uc->closure = closure;
+#if notyet
+ e_contact_load_uri (dest->priv->book_uri, dest->priv->uid, use_contact_cb, uc);
+#endif
+ } else {
+ if (cb)
+ cb (dest, NULL, closure);
+ }
+}
+
+EContact *
+eab_destination_get_contact (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ return dest->priv->contact;
+}
+
+const gchar *
+eab_destination_get_contact_uid (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ if (dest->priv->uid)
+ return dest->priv->uid;
+
+ if (dest->priv->contact)
+ return e_contact_get_const (dest->priv->contact, E_CONTACT_UID);
+
+ return NULL;
+}
+
+const gchar *
+eab_destination_get_book_uri (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ return dest->priv->book_uri;
+}
+
+gint
+eab_destination_get_email_num (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), -1);
+
+ if (dest->priv->contact == NULL && (dest->priv->book_uri == NULL || dest->priv->uid == NULL))
+ return -1;
+
+ return dest->priv->email_num;
+}
+
+const gchar *
+eab_destination_get_name (const EABDestination *dest)
+{
+ struct _EABDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EABDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->name == NULL) {
+ if (priv->contact != NULL) {
+ priv->name = e_contact_get (priv->contact, E_CONTACT_FULL_NAME);
+
+ if (priv->name == NULL || *priv->name == '\0') {
+ g_free (priv->name);
+ priv->name = e_contact_get (priv->contact, E_CONTACT_FILE_AS);
+ }
+
+ if (priv->name == NULL || *priv->name == '\0') {
+ g_free (priv->name);
+ if (e_contact_get (priv->contact, E_CONTACT_IS_LIST))
+ priv->name = g_strdup (_("Unnamed List"));
+ else
+ priv->name = g_strdup (eab_destination_get_email (dest));
+ }
+ } else if (priv->raw != NULL) {
+ CamelInternetAddress *addr = camel_internet_address_new ();
+
+ if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) {
+ const char *camel_name = NULL;
+
+ camel_internet_address_get (addr, 0, &camel_name, NULL);
+ priv->name = g_strdup (camel_name);
+ }
+
+ camel_object_unref (CAMEL_OBJECT (addr));
+ }
+ }
+
+ return priv->name;
+}
+
+const gchar *
+eab_destination_get_email (const EABDestination *dest)
+{
+ struct _EABDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EABDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->email == NULL) {
+ if (priv->contact != NULL) {
+ /* Pull the address out of the card. */
+ GList *email = e_contact_get (priv->contact, E_CONTACT_EMAIL);
+ if (email) {
+ char *e = g_list_nth_data (email, priv->email_num);
+
+ if (e)
+ priv->email = g_strdup (e);
+ }
+ if (email) {
+ g_list_foreach (email, (GFunc)g_free, NULL);
+ g_list_free (email);
+ }
+
+ } else if (priv->raw != NULL) {
+ CamelInternetAddress *addr = camel_internet_address_new ();
+
+ if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) {
+ const gchar *camel_email = NULL;
+ camel_internet_address_get (addr, 0, NULL, &camel_email);
+ priv->email = g_strdup (camel_email);
+ }
+
+ camel_object_unref (CAMEL_OBJECT (addr));
+ }
+
+ /* Force e-mail to be non-null... */
+ if (priv->email == NULL) {
+ priv->email = g_strdup ("");
+ }
+ }
+
+ return priv->email;
+}
+
+const gchar *
+eab_destination_get_address (const EABDestination *dest)
+{
+ struct _EABDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EABDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->addr == NULL) {
+ CamelInternetAddress *addr = camel_internet_address_new ();
+
+ if (eab_destination_is_evolution_list (dest)) {
+ GList *iter = dest->priv->list_dests;
+
+ while (iter) {
+ EABDestination *list_dest = EAB_DESTINATION (iter->data);
+
+ if (!eab_destination_is_empty (list_dest)) {
+ camel_internet_address_add (addr,
+ eab_destination_get_name (list_dest),
+ eab_destination_get_email (list_dest));
+ }
+ iter = g_list_next (iter);
+ }
+
+ priv->addr = camel_address_encode (CAMEL_ADDRESS (addr));
+ } else if (priv->raw) {
+
+ if (camel_address_unformat (CAMEL_ADDRESS (addr), priv->raw)) {
+ priv->addr = camel_address_encode (CAMEL_ADDRESS (addr));
+ }
+ } else {
+ camel_internet_address_add (addr,
+ eab_destination_get_name (dest),
+ eab_destination_get_email (dest));
+
+ priv->addr = camel_address_encode (CAMEL_ADDRESS (addr));
+ }
+
+ camel_object_unref (CAMEL_OBJECT (addr));
+ }
+
+ return priv->addr;
+}
+
+void
+eab_destination_set_raw (EABDestination *dest, const gchar *raw)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+ g_return_if_fail (raw != NULL);
+
+ if (dest->priv->raw == NULL || strcmp (dest->priv->raw, raw)) {
+ eab_destination_freeze (dest);
+
+ eab_destination_clear (dest);
+ dest->priv->raw = g_strdup (raw);
+ eab_destination_changed (dest);
+
+ eab_destination_thaw (dest);
+ }
+}
+
+const gchar *
+eab_destination_get_textrep (const EABDestination *dest, gboolean include_email)
+{
+ const char *name, *email;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ if (dest->priv->raw)
+ return dest->priv->raw;
+
+ name = eab_destination_get_name (dest);
+ email = eab_destination_get_email (dest);
+
+ if (eab_destination_from_contact (dest) && name != NULL && (!include_email || !email || !*email))
+ return name;
+
+ /* Make sure that our address gets quoted properly */
+ if (name && email && dest->priv->textrep == NULL) {
+ CamelInternetAddress *addr = camel_internet_address_new ();
+
+ camel_internet_address_add (addr, name, email);
+ g_free (dest->priv->textrep);
+ dest->priv->textrep = camel_address_format (CAMEL_ADDRESS (addr));
+ camel_object_unref (CAMEL_OBJECT (addr));
+ }
+
+ if (dest->priv->textrep != NULL)
+ return dest->priv->textrep;
+
+ if (email)
+ return email;
+
+ return "";
+}
+
+gboolean
+eab_destination_is_evolution_list (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+
+ if (dest->priv->list_dests == NULL
+ && dest->priv->contact != NULL
+ && e_contact_get (dest->priv->contact, E_CONTACT_IS_LIST)) {
+ GList *email = e_contact_get (dest->priv->contact, E_CONTACT_EMAIL);
+ if (email) {
+ GList *iter;
+ for (iter = email; iter; iter = iter->next) {
+ EABDestination *list_dest = eab_destination_import ((char *) iter->data);
+
+ if (list_dest)
+ dest->priv->list_dests = g_list_append (dest->priv->list_dests, list_dest);
+ }
+ }
+ }
+
+ return dest->priv->list_dests != NULL;
+}
+
+gboolean
+eab_destination_list_show_addresses (const EABDestination *dest)
+{
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), FALSE);
+
+ if (dest->priv->contact != NULL)
+ return GPOINTER_TO_UINT (e_contact_get (dest->priv->contact, E_CONTACT_LIST_SHOW_ADDRESSES));
+
+ return dest->priv->show_addresses;
+}
+
+gboolean
+eab_destination_get_html_mail_pref (const EABDestination *dest)
+{
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+
+ if (dest->priv->html_mail_override || dest->priv->contact == NULL)
+ return dest->priv->wants_html_mail;
+
+ return e_contact_get (dest->priv->contact, E_CONTACT_WANTS_HTML) ? TRUE : FALSE;
+}
+
+static void
+set_book (EABDestination *dest, EBook *book)
+{
+ if (dest->priv->book && dest->priv->book != book) {
+ g_object_unref (dest->priv->book);
+ }
+
+ dest->priv->book = book;
+
+ if (book)
+ g_object_ref (book);
+}
+
+static void
+name_and_email_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
+{
+ EABDestination *dest = EAB_DESTINATION (closure);
+
+ if (status == E_BOOK_ERROR_OK && g_list_length ((GList *) contacts) == 1) {
+ EContact *contact = E_CONTACT (contacts->data);
+ const char *email = eab_destination_get_email (dest);
+ int email_num = 0;
+
+#if notyet
+ if (eab_destination_is_valid (dest) && email && *email) {
+ email_num = e_contact_email_find_number (contact, eab_destination_get_email (dest));
+ }
+#endif
+
+ if (email_num >= 0) {
+ const char *book_uri;
+
+ book_uri = e_book_get_uri (book);
+
+ dest->priv->contact_loaded = TRUE;
+ eab_destination_set_contact (dest, contact, email_num);
+ eab_destination_set_book_uri (dest, book_uri);
+ g_signal_emit (dest, eab_destination_signals[CONTACT_LOADED], 0);
+ }
+ }
+
+ if (!dest->priv->contact_loaded)
+ dest->priv->cannot_load = TRUE;
+
+ g_object_unref (dest); /* drop the reference held by the query */
+}
+
+
+static void
+nickname_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
+{
+ EABDestination *dest = EAB_DESTINATION (closure);
+
+ if (status == E_BOOK_ERROR_OK) {
+ if (g_list_length ((GList *) contacts) == 1) {
+ const char *book_uri;
+
+ book_uri = e_book_get_uri (book);
+
+ dest->priv->contact_loaded = TRUE;
+ eab_destination_set_contact (dest, E_CONTACT (contacts->data), 0); /* Uses primary e-mail by default. */
+ eab_destination_set_book_uri (dest, book_uri);
+ g_signal_emit (dest, eab_destination_signals[CONTACT_LOADED], 0);
+
+ g_object_unref (dest); /* drop the reference held by the query */
+
+ } else {
+ /* We can only end up here if we don't look at all like an e-mail address, so
+ we do a name-only query on the textrep */
+
+ eab_name_and_email_query (book,
+ eab_destination_get_textrep (dest, FALSE),
+ NULL,
+ name_and_email_cb,
+ dest);
+ }
+ } else {
+ /* Something went wrong with the query: drop our ref to the destination and return. */
+ g_object_unref (dest);
+ }
+}
+
+static void
+launch_load_contact_query (EABDestination *dest)
+{
+ if (! eab_destination_is_valid (dest)) {
+ /* If it doesn't look like an e-mail address, see if it is a nickname. */
+ eab_nickname_query (dest->priv->book,
+ eab_destination_get_textrep (dest, FALSE),
+ nickname_cb,
+ dest);
+
+ } else {
+ eab_name_and_email_query (dest->priv->book,
+ eab_destination_get_name (dest),
+ eab_destination_get_email (dest),
+ name_and_email_cb,
+ dest);
+ }
+}
+
+void
+eab_destination_load_contact (EABDestination *dest, EBook *book)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+ g_return_if_fail (book == NULL || E_IS_BOOK (book));
+
+ if (eab_destination_is_evolution_list (dest))
+ return;
+
+ if (eab_destination_contains_contact (dest))
+ return;
+
+ if (dest->priv->cannot_load)
+ return;
+
+ eab_destination_cancel_contact_load (dest);
+
+ set_book (dest, book);
+
+ /* Handle the case of an EABDestination containing a contact URL */
+ if (eab_destination_contains_contact (dest)) {
+ eab_destination_use_contact (dest, NULL, NULL);
+ return;
+ }
+
+ /* We hold a reference to ourselves until our query is complete. */
+ g_object_ref (dest);
+ launch_load_contact_query (dest);
+}
+
+static int
+do_load_delayed (gpointer ptr)
+{
+ EABDestination *dest = EAB_DESTINATION (ptr);
+
+ eab_destination_load_contact (dest, dest->priv->book);
+ return FALSE;
+}
+
+void
+eab_destination_load_contact_delayed (EABDestination *dest, EBook *book, gint delay)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+ g_return_if_fail (book == NULL || E_IS_BOOK (book));
+
+ if (delay < 0)
+ delay = 500;
+
+ eab_destination_cancel_contact_load (dest);
+
+ set_book (dest, book);
+
+ dest->priv->pending_contact_load = g_timeout_add (delay, do_load_delayed, dest);
+}
+
+void
+eab_destination_cancel_contact_load (EABDestination *dest)
+{
+ g_return_if_fail (EAB_IS_DESTINATION (dest));
+
+ if (dest->priv->pending_contact_load) {
+ g_source_remove (dest->priv->pending_contact_load);
+ dest->priv->pending_contact_load = 0;
+ }
+}
+
+gboolean
+eab_destination_unload_contact (EABDestination *dest)
+{
+ char *email;
+
+ g_return_val_if_fail (EAB_IS_DESTINATION (dest), FALSE);
+
+ if (!eab_destination_contains_contact (dest))
+ return FALSE;
+
+ email = g_strdup (eab_destination_get_email (dest));
+
+ if (email == NULL)
+ return FALSE;
+
+ eab_destination_freeze (dest);
+ eab_destination_clear (dest);
+ eab_destination_set_raw (dest, email);
+ g_free (email);
+ eab_destination_thaw (dest);
+
+ return TRUE;
+}
+
+/*
+ * Destination import/export
+ */
+
+gchar *
+eab_destination_get_address_textv (EABDestination **destv)
+{
+ int i, j, len = 0;
+ char **strv;
+ char *str;
+
+ g_return_val_if_fail (destv, NULL);
+
+ /* Q: Please tell me this is only for assertion
+ reasons. If this is considered to be ok behavior then you
+ shouldn't use g_return's. Just a reminder ;-)
+
+ A: Yes, this is just an assertion. (Though it does find the
+ length of the vector in the process...)
+ */
+ while (destv[len]) {
+ g_return_val_if_fail (EAB_IS_DESTINATION (destv[len]), NULL);
+ len++;
+ }
+
+ strv = g_new0 (char *, len + 1);
+ for (i = 0, j = 0; destv[i]; i++) {
+ if (!eab_destination_is_empty (destv[i])) {
+ const char *addr = eab_destination_get_address (destv[i]);
+ strv[j++] = addr ? (char *) addr : "";
+ }
+ }
+
+ str = g_strjoinv (", ", strv);
+
+ g_free (strv);
+
+ return str;
+}
+
+xmlNodePtr
+eab_destination_xml_encode (const EABDestination *dest)
+{
+ xmlNodePtr dest_node;
+ const char *str;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ dest_node = xmlNewNode (NULL, "destination");
+
+ str = eab_destination_get_name (dest);
+ if (str)
+ xmlNewTextChild (dest_node, NULL, "name", str);
+
+ if (!eab_destination_is_evolution_list (dest)) {
+ str = eab_destination_get_email (dest);
+ if (str)
+ xmlNewTextChild (dest_node, NULL, "email", str);
+ } else {
+ GList *iter = dest->priv->list_dests;
+
+ while (iter) {
+ EABDestination *list_dest = EAB_DESTINATION (iter->data);
+ xmlNodePtr list_node = xmlNewNode (NULL, "list_entry");
+
+ str = eab_destination_get_name (list_dest);
+ if (str)
+ xmlNewTextChild (list_node, NULL, "name", str);
+
+ str = eab_destination_get_email (list_dest);
+ if (str)
+ xmlNewTextChild (list_node, NULL, "email", str);
+
+ xmlAddChild (dest_node, list_node);
+
+ iter = g_list_next (iter);
+ }
+
+ xmlNewProp (dest_node, "is_list", "yes");
+ xmlNewProp (dest_node, "show_addresses",
+ eab_destination_list_show_addresses (dest) ? "yes" : "no");
+ }
+
+ str = eab_destination_get_book_uri (dest);
+ if (str) {
+ xmlNewTextChild (dest_node, NULL, "book_uri", str);
+ }
+
+ str = eab_destination_get_contact_uid (dest);
+ if (str) {
+ char buf[16];
+
+ xmlNodePtr uri_node = xmlNewTextChild (dest_node, NULL, "card_uid", str);
+ g_snprintf (buf, 16, "%d", eab_destination_get_email_num (dest));
+ xmlNewProp (uri_node, "email_num", buf);
+ }
+
+ xmlNewProp (dest_node, "html_mail", eab_destination_get_html_mail_pref (dest) ? "yes" : "no");
+
+ xmlNewProp (dest_node, "auto_recipient",
+ eab_destination_is_auto_recipient (dest) ? "yes" : "no");
+
+ return dest_node;
+}
+
+gboolean
+eab_destination_xml_decode (EABDestination *dest, xmlNodePtr node)
+{
+ char *name = NULL, *email = NULL, *book_uri = NULL, *card_uid = NULL;
+ gboolean is_list = FALSE, show_addr = FALSE, auto_recip = FALSE;
+ gboolean html_mail = FALSE;
+ GList *list_dests = NULL;
+ int email_num = -1;
+ char *tmp;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
+
+ if (strcmp (node->name, "destination"))
+ return FALSE;
+
+ tmp = xmlGetProp (node, "html_mail");
+ if (tmp) {
+ html_mail = !strcmp (tmp, "yes");
+ xmlFree (tmp);
+ }
+
+ tmp = xmlGetProp (node, "is_list");
+ if (tmp) {
+ is_list = !strcmp (tmp, "yes");
+ xmlFree (tmp);
+ }
+
+ tmp = xmlGetProp (node, "show_addresses");
+ if (tmp) {
+ show_addr = !strcmp (tmp, "yes");
+ xmlFree (tmp);
+ }
+
+ tmp = xmlGetProp (node, "auto_recipient");
+ if (tmp) {
+ auto_recip = !strcmp (tmp, "yes");
+ xmlFree (tmp);
+ }
+
+ node = node->xmlChildrenNode;
+ while (node) {
+ if (!strcmp (node->name, "name")) {
+ tmp = xmlNodeGetContent (node);
+ g_free (name);
+ name = g_strdup (tmp);
+ xmlFree (tmp);
+ } else if (!is_list && !strcmp (node->name, "email")) {
+ tmp = xmlNodeGetContent (node);
+ g_free (email);
+ email = g_strdup (tmp);
+ xmlFree (tmp);
+ } else if (is_list && !strcmp (node->name, "list_entry")) {
+ xmlNodePtr subnode = node->xmlChildrenNode;
+ char *list_name = NULL, *list_email = NULL;
+
+ while (subnode) {
+ if (!strcmp (subnode->name, "name")) {
+ tmp = xmlNodeGetContent (subnode);
+ g_free (list_name);
+ list_name = g_strdup (tmp);
+ xmlFree (tmp);
+ } else if (!strcmp (subnode->name, "email")) {
+ tmp = xmlNodeGetContent (subnode);
+ g_free (list_email);
+ list_email = g_strdup (tmp);
+ xmlFree (tmp);
+ }
+
+ subnode = subnode->next;
+ }
+
+ if (list_name || list_email) {
+ EABDestination *list_dest = eab_destination_new ();
+
+ if (list_name)
+ eab_destination_set_name (list_dest, list_name);
+ if (list_email)
+ eab_destination_set_email (list_dest, list_email);
+
+ g_free (list_name);
+ g_free (list_email);
+
+ list_dests = g_list_append (list_dests, list_dest);
+ }
+ } else if (!strcmp (node->name, "book_uri")) {
+ tmp = xmlNodeGetContent (node);
+ g_free (book_uri);
+ book_uri = g_strdup (tmp);
+ xmlFree (tmp);
+ } else if (!strcmp (node->name, "card_uid")) {
+ tmp = xmlNodeGetContent (node);
+ g_free (card_uid);
+ card_uid = g_strdup (tmp);
+ xmlFree (tmp);
+
+ tmp = xmlGetProp (node, "email_num");
+ email_num = atoi (tmp);
+ xmlFree (tmp);
+ }
+
+ node = node->next;
+ }
+
+ eab_destination_freeze (dest);
+
+ eab_destination_clear (dest);
+
+ if (name) {
+ eab_destination_set_name (dest, name);
+ g_free (name);
+ }
+ if (email) {
+ eab_destination_set_email (dest, email);
+ g_free (email);
+ }
+ if (book_uri) {
+ eab_destination_set_book_uri (dest, book_uri);
+ g_free (book_uri);
+ }
+ if (card_uid) {
+ eab_destination_set_contact_uid (dest, card_uid, email_num);
+ g_free (card_uid);
+ }
+ if (list_dests)
+ dest->priv->list_dests = list_dests;
+
+ dest->priv->html_mail_override = TRUE;
+ dest->priv->wants_html_mail = html_mail;
+
+ dest->priv->show_addresses = show_addr;
+
+ dest->priv->auto_recipient = auto_recip;
+
+ eab_destination_thaw (dest);
+
+ return TRUE;
+}
+
+/* FIXME: Make utf-8 safe */
+static gchar *
+null_terminate_and_remove_extra_whitespace (xmlChar *xml_in, gint size)
+{
+ gboolean skip_white = FALSE;
+ char *xml, *r, *w;
+
+ if (xml_in == NULL || size <= 0)
+ return NULL;
+
+ xml = g_strndup (xml_in, size);
+ r = w = xml;
+
+ while (*r) {
+ if (*r == '\n' || *r == '\r') {
+ skip_white = TRUE;
+ } else {
+ gboolean is_space = isspace (*r);
+
+ *w = *r;
+
+ if (!(skip_white && is_space))
+ w++;
+ if (!is_space)
+ skip_white = FALSE;
+ }
+ r++;
+ }
+
+ *w = '\0';
+
+ return xml;
+}
+
+gchar *
+eab_destination_export (const EABDestination *dest)
+{
+ xmlNodePtr dest_node;
+ xmlDocPtr dest_doc;
+ xmlChar *buffer = NULL;
+ int size = -1;
+ char *str;
+
+ g_return_val_if_fail (dest && EAB_IS_DESTINATION (dest), NULL);
+
+ dest_node = eab_destination_xml_encode (dest);
+ if (dest_node == NULL)
+ return NULL;
+
+ dest_doc = xmlNewDoc (XML_DEFAULT_VERSION);
+ xmlDocSetRootElement (dest_doc, dest_node);
+
+ xmlDocDumpMemory (dest_doc, &buffer, &size);
+ xmlFreeDoc (dest_doc);
+
+ str = null_terminate_and_remove_extra_whitespace (buffer, size);
+ xmlFree (buffer);
+
+ return str;
+}
+
+EABDestination *
+eab_destination_import (const gchar *str)
+{
+ EABDestination *dest = NULL;
+ xmlDocPtr dest_doc;
+
+ if (!(str && *str))
+ return NULL;
+
+ dest_doc = xmlParseMemory ((char *) str, strlen (str));
+ if (dest_doc && dest_doc->xmlRootNode) {
+ dest = eab_destination_new ();
+ if (! eab_destination_xml_decode (dest, dest_doc->xmlRootNode)) {
+ g_object_unref (dest);
+ dest = NULL;
+ }
+ }
+ xmlFreeDoc (dest_doc);
+
+ return dest;
+}
+
+gchar *
+eab_destination_exportv (EABDestination **destv)
+{
+ xmlDocPtr destv_doc;
+ xmlNodePtr destv_node;
+ xmlChar *buffer = NULL;
+ int i, size = -1;
+ char *str;
+
+ if (destv == NULL || *destv == NULL)
+ return NULL;
+
+ destv_doc = xmlNewDoc (XML_DEFAULT_VERSION);
+ destv_node = xmlNewNode (NULL, "destinations");
+ xmlDocSetRootElement (destv_doc, destv_node);
+
+ for (i = 0; destv[i]; i++) {
+ if (! eab_destination_is_empty (destv[i])) {
+ xmlNodePtr dest_node = eab_destination_xml_encode (destv[i]);
+ if (dest_node)
+ xmlAddChild (destv_node, dest_node);
+ }
+ }
+
+ xmlDocDumpMemory (destv_doc, &buffer, &size);
+ xmlFreeDoc (destv_doc);
+
+ str = null_terminate_and_remove_extra_whitespace (buffer, size);
+ xmlFree (buffer);
+
+ return str;
+}
+
+EABDestination **
+eab_destination_importv (const gchar *str)
+{
+ GPtrArray *dest_array = NULL;
+ xmlDocPtr destv_doc;
+ xmlNodePtr node;
+ EABDestination **destv = NULL;
+
+ if (!(str && *str))
+ return NULL;
+
+ destv_doc = xmlParseMemory ((char *)str, strlen (str));
+ if (destv_doc == NULL)
+ return NULL;
+
+ node = destv_doc->xmlRootNode;
+
+ if (strcmp (node->name, "destinations"))
+ goto finished;
+
+ node = node->xmlChildrenNode;
+
+ dest_array = g_ptr_array_new ();
+
+ while (node) {
+ EABDestination *dest;
+
+ dest = eab_destination_new ();
+ if (eab_destination_xml_decode (dest, node) && !eab_destination_is_empty (dest)) {
+ g_ptr_array_add (dest_array, dest);
+ } else {
+ g_object_unref (dest);
+ }
+
+ node = node->next;
+ }
+
+ /* we need destv to be NULL terminated */
+ g_ptr_array_add (dest_array, NULL);
+
+ destv = (EABDestination **) dest_array->pdata;
+ g_ptr_array_free (dest_array, FALSE);
+
+ finished:
+ xmlFreeDoc (destv_doc);
+
+ return destv;
+}
+
+EABDestination **
+eab_destination_list_to_vector_sized (GList *list, int n)
+{
+ EABDestination **destv;
+ int i = 0;
+
+ if (n == -1)
+ n = g_list_length (list);
+
+ if (n == 0)
+ return NULL;
+
+ destv = g_new (EABDestination *, n + 1);
+ while (list != NULL && i < n) {
+ destv[i] = EAB_DESTINATION (list->data);
+ list->data = NULL;
+ i++;
+ list = g_list_next (list);
+ }
+ destv[i] = NULL;
+
+ return destv;
+}
+
+EABDestination **
+eab_destination_list_to_vector (GList *list)
+{
+ return eab_destination_list_to_vector_sized (list, -1);
+}
+
+void
+eab_destination_freev (EABDestination **destv)
+{
+ int i;
+
+ if (destv) {
+ for (i = 0; destv[i] != NULL; ++i) {
+ g_object_unref (destv[i]);
+ }
+ g_free (destv);
+ }
+
+}
+
+#if notyet
+static void
+touch_cb (EBook *book, const gchar *addr, ECard *card, gpointer closure)
+{
+ if (book != NULL && card != NULL) {
+ e_card_touch (card);
+ d(g_message ("Use score for \"%s\" is now %f", addr, e_card_get_use_score (card)));
+ e_book_commit_card (book, card, NULL, NULL);
+ }
+}
+#endif
+
+void
+eab_destination_touch (EABDestination *dest)
+{
+#if notyet
+ const char *email;
+
+ g_return_if_fail (dest && EAB_IS_DESTINATION (dest));
+
+ if (!eab_destination_is_auto_recipient (dest)) {
+ email = eab_destination_get_email (dest);
+
+ if (email)
+ e_book_query_address_default (email, touch_cb, NULL);
+ }
+#endif
+}
+
+void
+eab_destination_touchv (EABDestination **destv)
+{
+#if notyet
+ int i;
+
+ g_return_if_fail (destv != NULL);
+
+ for (i = 0; destv[i] != NULL; ++i) {
+ eab_destination_touch (destv[i]);
+ }
+#endif
+}
diff --git a/addressbook/util/eab-destination.h b/addressbook/util/eab-destination.h
new file mode 100644
index 0000000000..452d893e44
--- /dev/null
+++ b/addressbook/util/eab-destination.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * eab-destination.h
+ *
+ * Copyright (C) 2001-2003 Ximian, Inc.
+ *
+ * Authors: Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#ifndef __E_DESTINATION_H__
+#define __E_DESTINATION_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <ebook/e-contact.h>
+#include <ebook/e-book.h>
+#include <libxml/tree.h>
+
+#define EAB_TYPE_DESTINATION (eab_destination_get_type ())
+#define EAB_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_DESTINATION, EABDestination))
+#define EAB_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EAB_TYPE_DESTINATION, EABDestinationClass))
+#define EAB_IS_DESTINATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_DESTINATION))
+#define EAB_IS_DESTINATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_DESTINATION))
+#define EAB_DESTINATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EAB_TYPE_DESTINATION, EABDestinationClass))
+
+typedef struct _EABDestination EABDestination;
+typedef struct _EABDestinationClass EABDestinationClass;
+
+typedef void (*EABDestinationContactCallback) (EABDestination *dest, EContact *contact, gpointer closure);
+
+struct _EABDestinationPrivate;
+
+struct _EABDestination {
+ GObject object;
+
+ struct _EABDestinationPrivate *priv;
+};
+
+struct _EABDestinationClass {
+ GObjectClass parent_class;
+
+ void (*changed) (EABDestination *dest);
+ void (*contact_loaded) (EABDestination *dest);
+};
+
+GType eab_destination_get_type (void);
+
+
+EABDestination *eab_destination_new (void);
+void eab_destination_changed (EABDestination *);
+EABDestination *eab_destination_copy (const EABDestination *);
+void eab_destination_clear (EABDestination *);
+
+gboolean eab_destination_is_empty (const EABDestination *);
+gboolean eab_destination_equal (const EABDestination *a, const EABDestination *b);
+
+void eab_destination_set_contact (EABDestination *, EContact *contact, gint email_num);
+
+void eab_destination_set_name (EABDestination *, const gchar *name);
+void eab_destination_set_email (EABDestination *, const gchar *email);
+
+void eab_destination_set_html_mail_pref (EABDestination *, gboolean);
+
+gboolean eab_destination_contains_contact (const EABDestination *);
+
+gboolean eab_destination_is_auto_recipient (const EABDestination *);
+void eab_destination_set_auto_recipient (EABDestination *, gboolean value);
+
+void eab_destination_use_contact (EABDestination *, EABDestinationContactCallback cb, gpointer closure);
+
+EContact *eab_destination_get_contact (const EABDestination *);
+gint eab_destination_get_email_num (const EABDestination *);
+
+const gchar *eab_destination_get_name (const EABDestination *); /* "Jane Smith" */
+const gchar *eab_destination_get_email (const EABDestination *); /* "jane@assbarn.com" */
+const gchar *eab_destination_get_address (const EABDestination *);; /* "Jane Smith <jane@assbarn.com>" (or a comma-sep set of such for a list) */
+
+void eab_destination_set_raw (EABDestination *, const gchar *free_form_string);
+const gchar *eab_destination_get_textrep (const EABDestination *, gboolean include_email); /* "Jane Smith" or "jane@assbarn.com" */
+
+gboolean eab_destination_is_evolution_list (const EABDestination *);
+gboolean eab_destination_list_show_addresses (const EABDestination *);
+
+/* If true, they want HTML mail. */
+gboolean eab_destination_get_html_mail_pref (const EABDestination *);
+
+void eab_destination_load_contact (EABDestination *, EBook *);
+void eab_destination_load_contact_delayed (EABDestination *, EBook *, gint delay); /* delay < 0: "default" */
+void eab_destination_cancel_contact_load (EABDestination *);
+gboolean eab_destination_unload_contact (EABDestination *);
+
+gchar *eab_destination_get_address_textv (EABDestination **);
+
+gchar *eab_destination_export (const EABDestination *);
+EABDestination *eab_destination_import (const gchar *str);
+
+gchar *eab_destination_exportv (EABDestination **);
+EABDestination **eab_destination_importv (const gchar *str);
+
+EABDestination **eab_destination_list_to_vector_sized (GList *, int n);
+EABDestination **eab_destination_list_to_vector (GList *);
+
+void eab_destination_freev (EABDestination **);
+
+void eab_destination_touch (EABDestination *);
+void eab_destination_touchv (EABDestination **);
+
+
+#endif /* __EAB_DESTINATION_H__ */
+
diff --git a/addressbook/util/eab-marshal.list b/addressbook/util/eab-marshal.list
new file mode 100644
index 0000000000..680ea039a3
--- /dev/null
+++ b/addressbook/util/eab-marshal.list
@@ -0,0 +1,5 @@
+NONE:NONE
+NONE:BOOL
+NONE:POINTER
+NONE:STRING
+NONE:INT
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 0d6fb57dfe..023e9f7ecd 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,9 +1,239 @@
-2003-10-17 Jeffrey Stedfast <fejj@ximian.com>
+2003-10-21 Rodrigo Moya <rodrigo@ximian.com>
- * conduits/calendar/Makefile.am: Fixed for libical changes.
+ * gui/calendar-component.c (calendar_component_init): fixed
+ a leak caused by only freeing 'base_uri' in some cases.
+
+2003-10-21 JP Rosevear <jpr@ximian.com>
+
+ * gui/control-factory.c (get_prop): fix parse error
+ (set_prop): gnome_calendar_open was renamed
+
+ * conduits/todo/todo-conduit.c (start_calendar_server): adapt to
+ the cal_client_new changes and the lack of a default calendar
+ routine
+ (pre_sync): don't have to pass a type for the default object any
+ more
+
+ * conduits/calendar/calendar-conduit.c (start_calendar_server):
+ adapt to the cal_client_new changes and the lack of a default
+ calendar routine
+ (pre_sync): don't have to pass a type for the default object any
+ more
+
+ * cal-client/cal-client.c (cal_client_open_async): add FIXME
+ comment
+
+2003-10-21 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: store recurrences per object.
+ (free_object): free correctly the CalBackendFileObject's
+ contained in 'priv->comp_uid_hash'.
+ (lookup_component, check_dup_uid, add_component, remove_component,
+ match_object_sexp):
+ adapted to changes in comp_uid_hash.
+
+2003-10-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.[ch] (gnome_calendar_add_event_uri): renamed
+ from gnome_calendar_open.
+
+ * gui/calendar-component.c (load_uri_for_source): call
+ gnome_calendar_add_event_uri instead of setting the URI property on
+ the Bonobo control.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/migration.c (process_calendar_dir): process subfolders.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/migration.[ch] (migrate_old_calendars): new function.
+
+ * gui/calendar-component.c (calendar_component_init): call
+ the above function to migrate from old setups.
+
+ * gui/Makefile.am: added new files.
+
+2003-10-17 Jeffrey Stedfast <fejj@ximian.com>
+
+ * conduits/calendar/Makefile.am: Fixed for libical build changes.
* conduits/todo/Makefile.am: Same.
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (on_print): call
+ e_cal_view_get_visible_time_range, not the gnome_calendar_
+ version.
+ (e_cal_view_new_appointment_for, e_cal_view_new_appointment,
+ e_cal_view_edit_appointment): new functions.
+
+ * gui/gnome-cal.[ch] (gnome_calendar_new_appointment_for,
+ gnome_calendar_new_appointment, gnome_calendar_edit_object):
+ removed these functions, now available in e-cal-view.
+
+ * gui/calendar-commands.c:
+ * gui/e-day-view.c:
+ * gui/e-week-view-event-item.c:
+ * gui/e-week-view.c: replaced calls to gnome_calendar_* with
+ e_cal_view_* equivalents.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.[ch] (e_cal_view_get_default_category):
+ (e_cal_view_set_default_category): new functions.
+ (e_cal_view_destroy): free the default_category field.
+
+ * gui/e-day-view.[ch] (e_day_view_set_default_category):
+ removed obsolete function.
+ (e_day_view_init, e_day_view_destroy, e_day_view_do_key_press):
+ use the ECalView's default_category.
+
+ * gui/e-week-view.[ch] (e_week_view_set_default_category):
+ removed obsolete function.
+ (e_week_view_init, e_week_view_destroy, e_week_view_do_key_press):
+ use the ECalView's default_category.
+
+ * gui/gnome-cal.c (gnome_calendar_set_query): set the query
+ also on the list view by using the priv->views array.
+ (search_bar_category_changed_cb, gnome_calendar_set_default_client):
+ use the priv->views array.
+ (gnome_calendar_get_calendar_model): return the model for the
+ current view widget.
+ (gnome_calendar_open): removed tasks opening code.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): if the user
+ presses Cancel, just terminate.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-component.c (calendar_component_init): create
+ directories for the newly-created calendars.
+
+ * gui/dialogs/new-calendar.c (create_new_source_with_group): use
+ e_mkdir_hier instead of mkdir.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-component.c (calendar_component_init): if no groups
+ are present in the configuration, create the "On This Computer"
+ group and the "Personal" and "Work" calendars on it.
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): moved the
+ source creation...
+ (create_new_source_with_group): ...here, and made the code create
+ the directory for the new calendar.
+
+2003-10-15 Hans Petter Jansson <hpj@ximian.com>
+
+ * gui/e-select-names-editable.c (e_selct_names_editable_get_address):
+ EDestination -> EABDestination.
+
+ * gui/gnome-cal.c (setup_widgets): evolution_dir -> ".evolution".
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-select-names-editable.c (e_select_names_editable_get_address):
+ use EABDestination instead of EDestination.
+
+ * gui/gnome-cal.c (gnome_calendar_open): disabled tasks opening code.
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-meeting-list-view.c: adapted to new addressbook API.
+
+ * gui/e-meeting-store.c: adapted to new addressbook API.
+ (find_zone): fixed usage of icalcomponent where an icalproperty
+ is expected.
+ (refresh_busy_periods): fixed call to cal_client_get_free_busy().
+
+ * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct):
+ added missing variable.
+
+2003-10-15 Jeffrey Stedfast <fejj@ximian.com>
+
+ * gui/dialogs/meeting-page.c: #include <gal/e-table/e-table.h>
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-meeting-list-view.c (start_addressbook_server):
+ updated to new addressbook API.
+ (book_open_cb): removed unneeded function, since we load
+ the local addressbook synchronously.
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/Makefile.am: added missing header directories.
+
+ * pcs/cal-factory.h: include <libical/ical.h>, not <ical.h>.
+
+ * gui/dialogs/meeting-page.c: added missing headers.
+ (meeting_page_construct): free 'backend_address' as returned
+ by cal_client_get_cal_address(). Removed code to create the
+ meeting model's ETable not removed with the merge.
+
+ * gui/e-meeting-list-view.c: updated addressbook headers.
+
+ * gui/gnome-cal.h: added missing ',' in the GnomeCalendarViewType
+ enum.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_update_query): dont set status
+ messages here, already set in e_cal_view_update_query.
+ (update_query): removed this function.
+ (e_day_view_recalc_day_starts): call e_day_view_update_query,
+ not update_query.
+
+ * gui/e-week-view.c (e_week_view_update_query): dont set status
+ messages here, already set in e_cal_view_update_query.
+
+ * gui/gnome-cal.c (adjust_query_for_view): new function to adjust
+ the query for the visible time range on a given view.
+ (gnome_calendar_set_query): call adjust_query_for_view for each
+ one of the views.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (e_cal_view_init): connect to signals on the
+ model we create here, so that we get notifications for changes.
+
+ * gui/gnome-cal.c (gnome_calendar_set_query): set the query
+ on all models.
+ (gnome_calendar_open): update the date navigator query.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal.c (cal_notify_timezone_requested): never send NULL
+ strings to ORBit.
+
+ * gui/e-cal-view.c (e_cal_view_create_popup_menu): removed
+ unneeded variables. Also, fixed a typo that was making the
+ menu options be disabled when they should be enabled.
+
+2003-10-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.[ch] (e_cal_model_get_client_for_uri): new function.
+
+ * gui/gnome-cal.[ch] (gnome_calendar_set_default_client): new function.
+
+ * gui/calendar-component.c (primary_source_selection_changed_callback):
+ set the default client on the calendar view to be the primary
+ selection on the source list.
+
+2003-10-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): set a default group
+ on the calendar group option menu and create the source if all checks
+ are passed.
+
+2003-10-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): set up widgets
+ loaded from the Glade file.
+
2003-10-10 Hans Petter Jansson <hpj@ximian.com>
* gui/Makefile.am (etspec_DATA): Add e-cal-list-view.etspec.
@@ -44,6 +274,66 @@
* gui/e-cal-list-view.[ch]: Implement ECalListView, subclassing
ECalView.
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.[ch]: added new widget, which implements
+ the dialog to create new calendars.
+
+ * gui/dialogs/new-calendar.glade: basic mockup of the dialog.
+
+ * gui/dialogs/Makefile.am: added new files.
+
+ * gui/calendar-commands.c (file_new_calendar_cb): open the new calendar
+ dialog to allow user to create a new cal.
+
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/control-factory.c (calendar_properties_init): pass the
+ BonoboControl to get_prop/set_prop.
+ (get_prop): obtain the GnomeCalendar from the control.
+ (set_prop): ditto, and when the URI property is changed,
+ sensitize the UI as approppriate.
+
+ * gui/calendar-commands.c (calendar_control_sensitize_calendar_commands):
+ made this function public.
+
+ * gui/calendar-commands.h: added new prototype.
+
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-commands.c (file_new_calendar_cb,
+ file_new_appointment_cb, file_new_event_cb, file_new_meeting_cb,
+ file_new_task_cb): callbacks for "New..." verbs.
+ (sensitize_calendar_commands): sensitize new verbs, and made it
+ sensitize correctly based on the set of clients currently loaded.
+ (sensitize_taskpad_commands): likewise.
+
+2003-10-09 Hans Petter Jansson <hpj@ximian.com>
+
+ * gui/e-cal-model.c (get_classification): Adapt to libical API changes.
+ (ecm_set_value_at): Break after each case, so we don't set the passed value
+ in more than one field.
+
+2003-10-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (e_cal_view_delete_selected_occurrence):
+ * cal-client/cal-client.c (cal_client_remove_object): added missing
+ argument when calling cal_client_remove_object_with_mod().
+
+2003-10-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added missing 'rid' argument to the
+ removeObject method.
+
+ * cal-client/cal-client.c (cal_client_remove_object_with_mod):
+ * pcs/cal-backend.h:
+ * pcs/cal-backend.c (cal_backend_remove_object):
+ * pcs/cal-backend-sync.h:
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object,
+ _cal_backend_remove_object):
+ * pcs/cal-backend-file.c (cal_backend_file_remove_object):
+ * pcs/cal.c (impl_cal_removeObject): adapted to changes in IDL.
+
2003-10-09 Jeffrey Stedfast <fejj@ximian.com>
* cal-client/Makefile.am: INCLUDE path fixes for changes made to
@@ -90,6 +380,165 @@
* gui/dialogs/task-details-page.glade: Make percent-complete of
task details dialog numeric only.
+2003-10-08 Chris Toshok <toshok@ximian.com>
+
+ * gui/dialogs/e-delegate-dialog.c (e_delegate_dialog_construct):
+ EDestination => EABDestination, and e_destination =>
+ eab_destination.
+ (e_delegate_dialog_get_delegate): same.
+ (e_delegate_dialog_get_delegate_name): same.
+
+ * gui/dialogs/comp-editor-util.c: remove unnecessary #include of
+ e-destination.h.
+
+ * gui/dialogs/alarm-options.c (alarm_to_malarm_widgets):
+ EDestination => EABDestination, and e_destination =>
+ eab_destination.
+ (malarm_widgets_to_alarm): same.
+
+ * gui/e-meeting-model.c (book_open_cb): track change to error
+ return codes.
+ (start_addressbook_server): use
+ e_book_async_get_default_addressbook.
+ (contacts_cb): rename cursor_cb to this, as we no longer get
+ passed a cursur, and we don't need to check the email address
+ since the query is now "is" instead of "contains".
+ (refresh_busy_periods): use an "is" query, and use
+ e_book_async_get_contacts instead of getting a CardCursor.
+ (process_section): this takes an EABDestination** instead of a
+ SimpleCardList*, which is gone.
+ (select_names_ok_cb): get "destinations" instead of
+ "simple_card_list".
+
+2003-10-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_is_read_only): fixed
+ documentation comments.
+
+ * gui/calendar-commands.c (sensitize_calendar_commands): figure
+ out read-only menu items to disable based on the currently
+ selected object's CalClient.
+
+2003-10-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c: set better error m,essages on the
+ E_CALENDAR_CHECK_STATUS macro.
+ (cal_client_get_error_message): new function.
+
+ * cal-client/cal-client.h: added new prototype.
+
+ * gui/dialogs/comp-editor.c (save_comp): use the GError argument
+ for the cal_client_create/_modify_object calls, and display the
+ error message coming from the backend.
+
+ * gui/comp-util.c (cal_comp_is_on_server): likewise.
+
+2003-10-07 Dan Winship <danw@ximian.com>
+
+ * idl/evolution-calendar.idl (getDefaultObject): Remove the "type"
+ arg; the backend knows what type it is
+
+ * pcs/cal.c (impl_Cal_getDefaultObject): Likewise
+
+ * pcs/cal-backend.c (cal_backend_get_default_object): Likewise
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_default_object,
+ _cal_backend_get_default_object): Likewise
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_default_object):
+ Likewise. (Use cal_backend_get_kind() instead.)
+
+ * cal-client/cal-client.c (cal_client_get_default_object):
+ Likewise
+
+ * gui/comp-util.c (cal_comp_event_new_with_defaults,
+ cal_comp_task_new_with_defaults): Update calls to
+ cal_client_get_default_object().
+
+ * pcs/cal-backend-sync.c (_cal_backend_get_static_capabilities):
+ Use the right cal notification
+
+2003-10-07 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ dont clone NULL icalcomponent's.
+
+2003-10-07 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_get_default_client): make sure we
+ always return a default client, if possible, since we rely on having
+ a default client in many places.
+
+ * gui/e-day-view.c (e_day_view_do_key_press): dont create event if
+ e_cal_model_create_component_with_defaults returns NULL.
+
+ * gui/e-week-view.c (e_week_view_do_key_press): dont create event if
+ e_cal_model_create_component_with_defaults returns NULL.
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ make sure the component has always an UID.
+
+ * gui/e-day-view.c (e_day_view_find_event_from_uid):
+ * gui/e-week-view.c (e_week_view_find_event_from_uid): check
+ pointers passed to strcmp().
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_open): added missing call to
+ cal_client_open().
+
+ * cal-client/cal-client.c (cal_client_new): fixed documentation
+ comments.
+ (cal_client_open): emit CAL_OPENED signal with appropriate status codes.
+ (open_sync): dont emit CAL_OPENED signal, it's already emitted in
+ cal_client_open().
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/comp-editor-factory.c (open_client):
+ * gui/gnome-cal.c (gnome_calendar_open, gnome_calendar_construct):
+ * gui/calendar-offline-handler.c (backend_go_offline, backend_go_online,
+ calendar_offline_handler_init): adapted to changes in cal_client and
+ manage GError's returned by cal_client_open.
+
+ * gui/e-itip-control.c: dont run anymore sub event loops.
+ (start_calendar_server): use synchronous interface for opening calendars.
+ (start_default_server): renamed it from *_async.
+ (start_calendar_server_cb): removed unneeded function.
+ (object_requested_cb): use sync interface.
+
+ * gui/e-tasks.c (e_tasks_construct): dont create the CalClient here.
+ (e_tasks_open): do it here, where we've got all the info needed.
+
+ * importers/icalendar-importer.c (update_single_object): killed warning.
+ (ical_importer_new, vcal_importer_new): don't create CalClient's here.
+ (load_file_fn): create them here.
+ (vcal_load_file_fn): and here.
+ (gnome_calendar_import_data_fn): fixed usage of cal_client_*.
+
+ * */*: integrated JP's changes for synchronous open's in cal_client
+ and one model per view instead of one model for all views.
+
+2003-10-02 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_modify_object): return FALSE
+ if the icalcomponent is NULL.
+
+ * gui/e-day-view.c (e_day_view_finish_resize): commit sequence on
+ CalComponent after changing start/end dates.
+
+2003-10-01 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): expand recurrences here.
+
+2003-09-30 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): removed.
+ (match_object_sexp): dont expand recurrences here.
+
2003-09-30 Mike Kestner <mkestner@ximian.com>
* cal-util/cal-util-marshal.list : new VOID:STRING,STRING,STRING
@@ -113,6 +562,519 @@
* conduits/calendar/Makefile.am: ditto
+2003-09-26 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove cal_added
+ signal
+
+2003-09-26 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (cal_get_backend): accessor
+ (cal_get_listener): ditto
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): update to new
+ routine name
+
+ * pcs/cal-backend.h: add protos
+
+ * pcs/cal-backend.c (cal_backend_init): init client mutex
+ (cal_backend_finalize): destroy client mutex
+ (cal_destroy_cb): just remove the client
+ (listener_died_cb): remove the client, the listener died so it
+ can't really do anything
+ (last_client_gone): signal the last client gone
+ (cal_backend_add_client): add a client with locking and listen for
+ the death of the listener
+ (cal_backend_remove_client): remove client
+
+2003-09-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-sync.c (_cal_backend_create_object): only free the
+ returned UID if it's not NULL.
+
+ * pcs/cal.c (cal_notify_object_created): dont send NULL strings to
+ ORBit code.
+
+2003-09-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/comp-util.c (cal_comp_is_on_server): free the icalcomponent
+ returned from cal_client_get_object, and return TRUE if we find
+ the component on the backend.
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): added missing case, so that
+ we also display recurrent meetings starting before the time range and
+ ending after the time range.
+
+ * cal-client/cal-listener.c (impl_notifyReadOnly): pass the
+ 'read_only' argument to the signal callback correctly (a gboolean
+ not a 'gboolean *').
+
+ * gui/comp-editor-factory.c (resolve_pending_requests): removed
+ the g_assert on 'oc->pending != NULL', since there are now cases
+ (local calendar) where we get to call this function (cal_opened_cb)
+ with no pending requests yet.
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * gui/calendar-commands.c (publish_freebusy_cmd): adapt to new
+ get_free_busy api
+
+ * conduits/calendar/calendar-conduit.c (post_sync): ditto
+ (pre_sync): ditto
+
+ * conduits/todo/todo-conduit.c (pre_sync): ditto
+ (post_sync): ditto
+
+ * gui/e-meeting-model.c (refresh_busy_periods): ditto
+
+ * gui/e-itip-control.c (send_freebusy): ditto
+
+ * gui/e-cal-view.c (on_publish): ditto
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (build_change_list): move here from
+ cal-client.c
+ (impl_notifyChanges): implement
+ (build_free_busy_list): util to create the GList of free busy
+ objects
+ (impl_notifyFreeBusy): implement
+ (cal_listener_class_init): set free busy and changes epv methods,
+ add signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_get_changes_cb): get changes call
+ back
+ (cal_get_free_busy_cb): get free busy call back
+ (cal_client_init): listen for free busy and changes signals
+ (cal_client_get_changes): convert to new threaded sync api
+ (cal_client_get_free_busy): ditto
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c: remove dead type conversion function
+ (impl_Cal_getChanges): implement by just calling, no return stuff
+ (impl_Cal_getFreeBusy): ditto
+ (cal_notify_changes): do getChanges callback
+ (cal_notify_free_busy): do getFreeBusy callback
+
+ * pcs/cal-backend.h: update protos, vmethods
+
+ * pcs/cal-backend.c (cal_backend_get_free_busy): call through
+ (cal_backend_get_changes): ditto
+
+ * pcs/cal-backend-sync.h: add vmethods, protos
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_changes): call
+ through
+ (cal_backend_sync_get_free_busy): ditto
+ (_cal_backend_get_changes): backend implementation, notify
+ (_cal_backend_get_free_busy): ditto
+ (cal_backend_sync_class_init): set free busy and changes
+ implementations
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): convert
+ to sync backend method
+ (cal_backend_file_compute_changes_foreach_key): remove from the
+ hash here
+ (cal_backend_file_compute_changes): no need to build the sequence
+ here
+ (cal_backend_file_get_changes): convert to sync backend method
+ (cal_backend_file_class_init): set sync backend methods for free
+ busy and changes
+
+ * idl/evolution-calendar.idl: convert getChanges and getFreeBusy
+ to new async api
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.h: remove dead result enums
+
+ * pcs/cal-backend.c: fix comments
+
+ * idl/evolution-calendar.idl: remove dead exceptions
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_default_object): send back the empty
+ string if the object is NULL
+ (cal_notify_object): ditto
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * gui/comp-editor-factory.c (edit_existing): convert to api
+ changes
+
+ * conduits/todo/todo-conduit.c (local_record_from_uid): ditto
+ (pre_sync): ditto
+
+ * conduits/calendar/calendar-conduit.c (local_record_from_uid):
+ ditto
+ (pre_sync): ditto
+
+ * importers/icalendar-importer.c (update_single_object): ditto
+
+ * gui/dialogs/comp-editor.c (obj_updated_cb): ditto
+
+ * gui/e-itip-control.c (get_real_item): ditto
+ (find_server): ditto
+
+ * gui/comp-util.c (cal_comp_is_on_server): ditto
+ (cal_comp_event_new_with_defaults): ditto
+ (cal_comp_task_new_with_defaults): ditto
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyDefaultObjectRequested):
+ implement
+ (impl_notifyObjectRequested): ditto
+ (cal_listener_class_init): set above epv implementations, add signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_default_object_requested_cb): get
+ default object callback
+ (cal_object_requested_cb): get object callback
+ (cal_client_init): listen for get and get default object signals
+ (cal_client_get_default_object): convert to new sync api
+ (cal_client_get_object): ditto
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_getDefaultObject): just call the backend, it
+ does the notification now
+ (impl_Cal_getObject): ditto
+ (cal_notify_default_object): do getDefaultObject response
+ (cal_notify_object): do getObject response
+
+ * pcs/cal-backend.h: remove vmethods, protos
+
+ * pcs/cal-backend.c: remove a couple of dead functions
+ (cal_backend_class_init): get_object_component is no longer a
+ vmethod
+ (cal_backend_get_default_object): call through
+ (cal_backend_get_object): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_default_object):
+ call through
+ (cal_backend_sync_get_object): ditto
+ (_cal_backend_discard_alarm): pass correct params to
+ cal_notify_discard_alarm
+ (_cal_backend_get_default_object): call through and notify
+ (_cal_backend_get_object): ditto
+ (cal_backend_sync_class_init): set backend implementations
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_default_object):
+ convert to sync backend method
+ (cal_backend_file_get_object): ditto
+ (cal_backend_file_compute_changes_foreach_key): just look up the
+ component rather than using the backend vmethod
+ (cal_backend_file_remove_object): return valid sync status codes
+ (cal_backend_file_class_init): move get_object, get_default_object
+ to sync class
+
+ * idl/evolution-calendar.idl: convert getObject and
+ getDefaultObject to new async idl
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (impl_Cal_discardAlarm): just call the backend
+ function, it does the notification
+ (cal_notify_alarm_discarded): notify of discard alarm call
+
+ * pcs/cal-backend.h: update proto
+
+ * pcs/cal-backend.c (cal_backend_discard_alarm): call through
+
+ * pcs/cal-backend-sync.h: add proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_discard_alarm): call
+ through
+ (_cal_backend_discard_alarm): call through and notify
+ (cal_backend_sync_class_init): set discard alarm implementation
+
+ * pcs/cal-backend-file.c (cal_backend_file_discard_alarm): match
+ sync backend vmethod
+ (cal_backend_file_class_init): set alarm vmethod implementation
+
+ * idl/evolution-calendar.idl: switch discardAlarm to new api
+
+ * gui/alarm-notify/alarm-queue.c (remove_queued_alarm): match new
+ api
+
+ * cal-client/cal-listener.h: add signal
+
+ * cal-client/cal-listener.c (impl_notifyAlarmDiscarded): implement
+ (cal_listener_class_init): add alarm, send, receive epv functions,
+ alarm signal
+
+ * cal-client/cal-client.h: update proto
+
+ * cal-client/cal-client.c (cal_alarm_discarded_cb): discardAlarm
+ callback
+ (cal_client_init): listen to discard alarm signal
+ (cal_client_discard_alarm): implement with new threaded sync api
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * idl/evolution-calendar.idl: remove unused user exceptions
+
+2003-09-24 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-util.[ch] (cal_backend_util_fill_alarm_instances_seq):
+ removed unneeded function.
+
+2003-09-24 JP Rosevear <jpr@ximian.com>
+
+ * conduits/*/*.c: adjust to new timezone api calls
+
+ * gui/*.c: ditto
+
+ * gui/dialogs/*.c: ditto
+
+ * cal-client/cal-listener.h: add new signals
+
+ * cal-client/cal-listener.c (convert_status): convert invalid
+ object as well
+ (impl_notifyTimezoneRequested): implement
+ (impl_notifyDefaultTimezoneSet): ditto
+ (cal_listener_class_init): set epv implementations for timezone
+ functions
+ (cal_listener_class_init): create timezone response signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c: fix return values all over the place
+ (cal_get_timezone_cb): getTimezone response
+ (cal_query_cb): setDefaultTimezone response
+ (cal_client_init): listen for new response signals
+ (cal_client_get_timezone): implement using new thread sync api
+ (cal_client_ensure_timezone_on_server): use add timezone call
+ (cal_client_set_default_timezone): oimplement using new thread sync
+ api
+
+ * cal-client/cal-client-types.h: add invalid object status code
+
+ * idl/evolution-calendar.idl: getQuery no longer raises any user
+ exceptions, remove dead types and exceptions
+
+2003-09-24 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: new protos
+
+ * pcs/cal.c (impl_Cal_getTimezone): call backend implementation
+ (impl_Cal_addTimezone): ditto
+ (impl_Cal_setDefaultTimezone): ditto
+ (cal_class_init): set epv implementations of timezone functions
+ (cal_notify_timezone_requested): notify of get timezone response
+ (cal_notify_default_timezone_set): notify of default timezone
+ being set
+
+ * pcs/cal-backend.h: new vmethods, protos
+
+ * pcs/cal-backend.c (cal_backend_class_init): init new timezone
+ vmethods
+ (cal_backend_get_timezone): call through
+ (cal_backend_set_default_timezone): ditto
+ (cal_backend_add_timezone): ditto
+ (cal_backend_internal_get_default_timezone): ditto
+ (cal_backend_internal_get_timezone): ditto
+
+ * pcs/cal-backend-sync.h: add vmethods, protos
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_timezone): call
+ through
+ (cal_backend_sync_set_default_timezone): ditto
+ (_cal_backend_set_default_timezone): call through and notify
+ (_cal_backend_get_timezone): ditto
+ (cal_backend_sync_class_init): set backend implementations for new
+ funcs
+
+ * pcs/cal-backend-object-sexp.c (func_occur_in_time_range): get
+ time_t values based on the zone
+
+ * pcs/cal-backend-file.c: reorg so we don't have to prototype
+ everything
+ (cal_backend_file_get_timezone): implement the sync backend way
+ (cal_backend_file_add_timezone): ditto
+ (cal_backend_file_set_default_timezone): ditto
+ (cal_backend_file_internal_get_default_timezone): internal method,
+ for sexp comparison
+ (cal_backend_file_internal_get_timezone): ditto
+
+ * idl/evolution-calendar.idl: convert timezone routines to async
+ api
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-object-sexp.c (func_occur_in_time_range): dont expand
+ recurrences, since they are supposed to be expanded in the backends.
+ (instance_occur_cb, resolve_tzid): removed unneeded functions.
+
+ * pcs/cal-backend-file.c (cal_backend_file_add_timezone): guard against
+ adding the timezone if it's already there.
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_object_created): notify with the object,
+ not the uid
+
+ * gui/e-cal-model.c (add_new_client): don't listen for
+ non-existent signal
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove dead proto
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove send result enum
+
+ * gui/itip-utils.c (comp_server_send): use the new send_objects
+ routine
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove send result enum
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove enum, protos
+
+ * cal-client/cal-client.c: remove remove status enum typing
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * importers/icalendar-importer.c (update_objects): new function
+ to manage the update of components, taking into account
+ VTIMEZONE components.
+ (process_item_fn, gnome_calendar_import_data_fn): use
+ update_objects instead of cal_client_update_objects.
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (impl_Cal_addTimezone): just call add_timezone, it
+ does the notification
+ (cal_notify_object_created): only notify the query if the object
+ matches
+ (cal_notify_object_removed): ditto
+
+ * pcs/cal-backend.h: update proto, vmethod
+
+ * pcs/cal-backend.c (cal_backend_add_timezone): returns void
+
+ * pcs/cal-backend-sync.h: update proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object): add the
+ object as an out param
+ (_cal_backend_remove_object): get the object and pass it in the
+ notification
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): kill
+ cal_backend_file_update_objects call, its more efficient to create
+ the comp ourselves; stamp the creation time, add the component to
+ the toplevel
+ (cal_backend_file_modify_object): kill the
+ cal_backend_file_update_objects call, add the component to the
+ toplevel
+ (cal_backend_file_remove_object): pass back the object when
+ removing
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-query.c (cal_query_finalize): disconnect the
+ signal handlers
+
+ * cal-client/cal-client.c (cal_client_get_query): unref the
+ listener when done
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (selection_received): add VTIMEZONE components
+ contained in the clipboard data to the backend.
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/dialogs/comp-editor.c (save_comp): modify and create instead
+ of update, simplify mod code
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_finish_long_event_resize): modify
+ the object instead of update, simplify the instance handling
+ (e_day_view_finish_resize): ditto
+ (e_day_view_on_top_canvas_drag_data_received): ditto
+ (e_day_view_on_main_canvas_drag_data_received): ditto
+
+2003-09-22 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_alarms_in_range): use
+ 'has-alarms' function in the search expression.
+
+ * pcs/cal-backend-object-sexp.c (func_has_alarms): new SExp function.
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_on_editing_stopped): create the
+ object if its not on the server or modify it if it is
+
+ * gui/e-week-view.c (e_week_view_on_editing_stopped): we return if
+ there is no text and it *not* on the server
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-week-view.c (e_week_view_on_editing_stopped): create the
+ object if its not on the server or modify it if it is
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.h: remove proto
+
+ * gui/gnome-cal.c: remove gnome_calendar_unrecur_selection
+
+ * gui/e-week-view.h: remove proto
+
+ * gui/e-week-view.c: remove e_week_view_unrecur_appointment
+
+ * gui/e-day-view.h: remove proto
+
+ * gui/e-day-view.c: remove e_day_view_unrecur_appointment
+
+ * gui/e-cal-view.c: remove on_unrecur_appointment (this is handled
+ better via recurrence id's now)
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-itip-control.c (update_attendee_status): ifdef out, leave
+ temporarily for reference, but otherwise it shouldn't be needed
+ (update_item): switch to using receive objects
+ (ok_clicked_cb): update item when receiving a reply
+
+ * gui/e-calendar-table.c (selection_received): switch to using
+ create object from update_objects
+
+ * gui/e-cal-view.c (selection_received_add_event): util routine to
+ prevent duplication
+ (selection_received): use above
+
+ * gui/e-cal-model.c (ecm_set_value_at): switch to using modify
+ object from update_objects
+ (ecm_append_row): switch to using create object from
+ update_objects
+
+ * gui/e-cal-model-calendar.c (ecmc_set_value_at): switch to using
+ modify object from update_objects
+
+ * gui/e-cal-model-tasks.c (ecmt_set_value_at): ditto
+
2003-09-22 Hans Petter Jansson <hpj@ximian.com>
* cal-util/Makefile.am (libical_util_la_LIBADD):
@@ -121,10 +1083,177 @@
* importers/Makefile.am (libevolution_calendar_importers_la_LIBADD):
libicalvcal.la -> libicalvcal-evolution.la
+
+2003-09-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: removed getAlarmsInRange and
+ getAlarmsForObject methods.
+
+ * pcs/cal.c (impl_Cal_getAlarmsInRange, impl_Cal_getAlarmsForObject):
+ removed unneeded CORBA methods.
+ (cal_class_init): dont set removed methods in the epv.
+
+ * pcs/cal-backend.[ch]: removed get_alarms_in_range and
+ get_alarms_for_object virtual methods.
+ (cal_backend_get_alarms_in_range, cal_backend_get_alarms_for_object):
+ removed.
+ (cal_backend_class_init): dont set removed virtual methods.
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_alarms_in_range,
+ cal_backend_file_get_alarms_for_object): removed.
+ (cal_backend_file_class_init): dont set removed virtual methods.
+
+2003-09-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_alarms_in_range): changed
+ to use queries.
+ (build_component_alarms_list): create the alarm list from a list
+ of iCalendar strings.
+ (build_alarm_instance_list): removed.
+ (cal_client_get_alarms_for_object): dont call the CORBA methods,
+ just get alarms by itself.
+
+2003-09-18 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-listener.[ch]: added "add_timezone" signal.
+ (impl_notifyTimezoneAdded): implemented new CalListener method.
+ (cal_listener_class_init): create "add_timezone" signal for the class.
+
+ * cal-client/cal-client.[ch] (cal_client_add_timezone): new function.
+ (cal_client_init): connect to "add_timezone" signal on the
+ CalListener.
+ (cal_add_timezone_cb): callback for the "add_timezone" signal.
+
+2003-09-18 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added 'notifyTimezoneAdded' method
+ to the Calendar::Listener interface.
+
+ * pcs/cal-backend-sync.[ch] (cal_backend_sync_add_timezone):
+ (_cal_backend_add_timezone): new functions for the new virtual
+ method implementation.
+
+ * pcs/cal.[ch] (cal_notify_timezone_added): new function.
+
+ * pcs/cal-backend-file.c (cal_backend_add_timezone): converted to
+ return a CalBackendSyncStatus.
+ (cal_backend_file_class_init): the 'add_timezone' method we implement
+ is the one in the CalBackendSync class.
+ (cancel_receive_object): added missing 'return'.
+ (free_cal_component): removed unused function.
+
+2003-09-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_add_timezone): added new
+ virtual method implementation.
+
+ * pcs/cal.c (impl_Cal_addTimezone): check return value from
+ cal_backend_add_timezone, and set an exception if an error is
+ returned.
+
+2003-09-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added addTimezone method.
+
+ * pcs/cal.c (impl_Cal_addTimezone): implemented new method.
+ (cal_class_init): set new method on the epv.
+
+ * pcs/cal-backend.[ch]: added 'add_timezone' virtual method.
+ (cal_backend_add_timezone): implemented new virtual method.
+
+ * pcs/cal-backend-file.c (cal_backend_file_modify_object): it's
+ cal_component_get_as_string, not cal_component_as_string.
+
+ * cal-client/cal-client.c (cal_client_ensure_timezone_on_server):
+ dont use anymore updateObjects method, use addTimezone instead.
+
2003-09-16 Rodrigo Moya <rodrigo@ximian.com>
* conduits/todo/Makefile.am: removed libwombat reference.
+2003-09-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): return
+ the UID of the added object.
+ (cal_backend_file_remove_object): ditto for old_object.
+
+2003-09-15 JP Rosevear <jpr@ximian.com>
+
+ * conduits/todo/todo-conduit.c (replace_record): switch to modify
+ object
+ (add_record): switch to using create object
+
+ * conduits/calendar/calendar-conduit.c (process_multi_day): switch
+ to using create object
+ (add_record): switch to using create object
+ (replace_record): switch to modify object
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyObjectsReceived):
+ implement listener method
+ (build_object_list): ditto
+ (cal_listener_class_init): create receive_objects and send_objects
+ signals
+
+ * cal-client/cal-client.h: add, update protos
+
+ * cal-client/cal-client.c (cal_objects_received_cb):
+ receive_objects callback
+ (cal_objects_sent_cb): send_objects callback
+ (cal_client_init): listen for above signals
+ (cal_client_create_object): pass back uid
+ (cal_client_receive_objects): implement
+ (cal_client_send_objects): ditto
+
+ * idl/evolution-calendar.idl: add receive/send objects methods and
+ yank updateObjects
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_receiveObjects): implement
+ (impl_Cal_sendObjects): ditto
+ (cal_class_init): add epv methods
+ (cal_notify_objects_received): notify of objects received call,
+ updating queries
+ (cal_notify_objects_sent): notify of objects sent
+
+ * pcs/cal-backend.h: remove proto
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove obj_updated
+ signal
+ (cal_backend_class_init): init vmethods properly
+ (cal_backend_receive_objects): call through
+ (cal_backend_send_objects): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_receive_objects): call
+ through
+ (cal_backend_sync_send_objects): ditto
+ (_cal_backend_receive_objects): call backend method and notify
+ (_cal_backend_send_objects): ditto
+ (cal_backend_sync_class_init): override send/receive object
+ vmethods
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): set
+ remove/send objects sync vmethods
+ (cal_backend_file_create_object): remove call to dead method
+ (cal_backend_file_remove_object): ditto
+ (cal_backend_file_modify_object): ditto
+ (cancel_received_object): cancel an object
+ (check_tzids): check we have all the tzid's for the object
+ (cal_backend_file_receive_objects): receive a bunch of objects via
+ itip
+ (cal_backend_file_send_objects): skeleton implementation
+
+2003-09-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added InvalidObject CallStatus.
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): implemented.
+ (cal_backend_file_modify_object): implemented.
+
2003-09-15 Harry Lu <harry.lu@sun.com>
* gui/apps_evolution_calendar.schemas: change last_notification_time's
@@ -137,6 +1266,219 @@
(e_week_view_jump_to_button_item): new function, jump to the day view.
(e_week_view_is_jump_button_visible): new function.
+
+2003-09-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal.c (cal_notify_cal_address, cal_notify_alarm_email_address,
+ cal_notify_ldap_attribute, cal_notify_static_capability):
+ make sure we always notify listeners, regardless of whether the
+ string is empty or not.
+
+ * cal-client/cal-client.c (check_capability): guard against using
+ NULL strings with strstr.
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (cal_opened_cb): listen for other query
+ signals
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyObjectCreated): implement
+ (impl_notifyObjectModified): implement
+ (cal_listener_class_init): assign epv implementations
+ (cal_listener_class_init): add create/modify object signals
+
+ * cal-client/cal-client.h: add protos
+
+ * cal-client/cal-client.c (cal_object_created_cb): object created
+ callback
+ (cal_object_modified_cb): object modified callback
+ (cal_client_init): listen for create/modify object signals from
+ the listener
+ (cal_client_create_object): call the create object method
+ (cal_client_modify_object): call the modify object method
+
+ * cal-client/client-test.c (cal_opened_cb): listen for all the
+ query signals, tidy
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (impl_Cal_createObject): implement
+ (impl_Cal_modifyObject): ditto
+ (cal_class_init): set epv methods for create/modify
+
+ * pcs/cal-backend.h: add protos, vmethod
+
+ * pcs/cal-backend.c (cal_backend_class_init): init new vmethods
+ (cal_backend_create_object): call through
+ (cal_backend_modify_object): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_create_object): call
+ through
+ (cal_backend_sync_modify_object): ditto
+ (_cal_backend_create_object): create object and notify
+ (_cal_backend_modify_object): modify object and notify
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object):
+ skeleton routine for creating objects
+ (cal_backend_file_modify_object): ditto for modifying
+
+ * idl/evolution-calendar.idl: add createObject and modifyObject
+ calls
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_object_removed): its uid, not uids
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/query.h: add protos
+
+ * pcs/query.c (query_object_matches): use the sexp to check for a
+ match
+ (query_notify_objects_added_1): notify of one object added to
+ query
+ (query_notify_objects_modified_1): ditto for modification
+ (query_notify_objects_removed_1): ditto for removal
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (cal_notify_object_created): notify of object creation
+ (cal_notify_object_modified): notify of object modification
+ (cal_notify_object_removed): use the _1 routines
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): this returns a
+ boolean
+ (cal_backend_file_update_objects): don't signal removals here now
+
+ * idl/evolution-calendar.idl: add object created and modified
+ responses
+
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (cal_notify_object_removed): notify relevant queries
+ of removal
+
+ * pcs/cal-backend.c (cal_backend_get_queries): ref the list before
+ passing it back
+
+ * pcs/cal-backend-sync.c (_cal_backend_remove_object): pass uid to
+ notification
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): don't unref the
+ component
+
+ * cal-client/client-test.c (cal_opened_cb): listen to objects
+ added signal
+ (objects_added_cb): print the object uid
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend-object-sexp.c (cal_backend_object_sexp_text):
+ return the base text
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (update_query): fix c/p typo
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (update_query): start the query
+
+ * gui/e-cal-model.c (update_query_for_client): ditto
+
+ * cal-client/client-test.c (cal_opened_cb): ditto
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-query.h: add proto
+
+ * cal-client/cal-query.c (cal_query_start): start the query
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/dialogs/delete-error.c (delete_error_dialog): accept GError
+ and base error messages on that
+
+ * gui/dialogs/delete-error.h: update proto
+
+ * gui/e-tasks.c (e_tasks_delete_completed): pass extra param to
+ cal_client_remove_object
+
+ * conduits/todo/todo-conduit.c (delete_record): ditto
+
+ * conduits/calendar/calendar-conduit.c (process_multi_day): ditto
+ (delete_record): ditto
+
+ * gui/gnome-cal.c (gnome_calendar_purge): ditto
+
+ * gui/dialogs/comp-editor.c (delete_comp): ditto
+
+ * gui/e-cal-view.c (e_cal_view_cut_clipboard): pass the error to
+ delete_error_dialog
+ (delete_event): ditto
+ (e_cal_view_delete_selected_occurrence): ditto
+
+ * gui/e-itip-control.c (remove_item): ditto
+
+ * gui/e-calendar-table.c (delete_selected_components): ditto
+
+ * cal-client/cal-listener.h: add signal
+
+ * cal-client/cal-listener.c (impl_notifyObjectRemoved): implement
+ (cal_listener_class_init): set object removed implementation and
+ create signal
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_object_removed_cb): object removal
+ callback
+ (cal_client_init): listen for object removal signal
+ (cal_client_remove_object_with_mod): make call synchronous
+ (cal_client_remove_object): pass new params
+
+ * pcs/cal.h: add proto
+
+ * pcs/cal.c (impl_Cal_removeObject): just call the backend
+ function
+ (cal_notify_object_removed): notify of removal
+
+ * pcs/cal-backend.h: remove and update protos, remove signal
+
+ * pcs/cal-backend.c (cal_backend_class_init): kill obj_removed
+ signal
+ (cal_backend_remove_object): there is no return value now
+
+ * pcs/cal-backend-sync.h: add vmethod, proto
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object): call
+ through
+ (_cal_backend_remove_object): remove the object and then do the
+ notification
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): remove
+ object is not part of the sync class
+ (cal_backend_file_update_objects): there is no more removed signal
+ (cal_backend_file_remove_object): return sync status codes
+
+ * idl/evolution-calendar.idl: make removeObject oneway and and a
+ notification method in the listener
+
+2003-09-11 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query.[ch] (query_get_text): new function.
+ (query_get_object_sexp): new function.
+
+ * pcs/cal-backend-file.c (cal_backend_file_start_query): implemented.
+
2003-09-11 Hans Petter Jansson <hpj@ximian.com>
* cal-util/Makefile.am (libcal_util_la_LIBADD):
@@ -193,12 +1535,279 @@
Statically link with wombat. Fix ETodo conduit.
(Mdk bug #5348)
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (impl_Cal_getObjectList): just call the backend, it
+ will do the notification now
+ (cal_notify_object_list): the list is a list of strings
+
+ * pcs/cal-backend.h: update vmethod, proto
+
+ * pcs/cal-backend.c (cal_backend_get_object_list): call through
+
+ * pcs/cal-backend-sync.h: add proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_object_list): call
+ through
+ (_cal_backend_get_object_list): get the list of objects from the
+ sync backend and do the notification
+ (cal_backend_sync_class_init): set vmethod implementation
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): the get
+ object list call is now part of the sync backend
+ (cal_backend_file_get_object_list): return a status and put the
+ object list in the passed in param
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.c (cal_backend_finalize): unref the elist
+ (cal_backend_init): init the query elist
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (dn_query_objects_added_cb): match new query
+ signals - just tag here
+ (dn_query_objects_modified_cb): always retag
+ (dn_query_objects_removed_cb): ditto
+ (update_query): connect to new signals
+ (gnome_calendar_destroy): we don't keep a list of expunging
+ queries
+ (gnome_calendar_purge): no need to do the
+ expunge async, just get the object list immediately
+
+ * gui/e-tasks.c (e_tasks_delete_completed): no need to do the
+ expunge async, just get the object list immediately
+
+ * gui/e-cal-model.c (query_objects_added_cb): callback for objects
+ added to the query
+ (query_objects_modified_cb): ditto for modifications
+ (query_objects_removed_cb): ditto for removed
+ (query_progress_cb): progress of the query
+ (query_done_cb): query is done
+ (update_query_for_client): connect to the new signals
+
+ * cal-client/client-test.c (cal_opened_cb): run a query
+
+ * cal-client/cal-query.c: we are given the listener now - listen
+ for signals from the listener and emit signals matching the api
+ changes
+
+ * cal-client/query-listener.[hc]: rewrite to match new query
+ listener methods and emit signals rather than using function
+ callbacks
+
+ * cal-client/cal-marshal.list: add to marshallers
+
+ * cal-client/cal-listener.h: add query signal
+
+ * cal-client/cal-listener.c (impl_notifyQuery): implement
+ (cal_listener_class_init): set notifyQuery method
+ (cal_listener_class_init): add query signal
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_query_cb): handle response to
+ getQuery
+ (cal_client_init): listen for query signal
+ (cal_client_get_query): get a query from the calendar
+
+ * pcs/query.h: update protos
+
+ * pcs/query.c: rewrite to implement the query start method and
+ provide notification calls
+
+ * pcs/cal.h: add proto
+
+ * pcs/cal.c (impl_Cal_getQuery): re-implement so the backend
+ doesn't create the query for us
+ (cal_notify_query): respond with the query
+
+ * pcs/cal-factory.c: re-order includes
+
+ * pcs/cal-common.h: add types
+
+ * pcs/cal-backend.h: update protos, vmethods
+
+ * pcs/cal-backend.c (cal_backend_class_init): init start_query
+ vmethod
+ (cal_backend_finalize): free mutex
+ (cal_backend_start_query): call through
+ (cal_backend_add_query): add a query to the list the backend is
+ running
+ (cal_backend_get_queries): get the query list
+
+ * pcs/cal-backend-object-sexp.h: add proto
+
+ * pcs/cal-backend-file.c (cal_backend_file_start_query): skeleton
+ for new backend implementation
+
+ * pcs/Makefile.am: don't build dead files
+
+ * idl/evolution-calendar.idl: make the getQuery call async, make
+ the query listener calls oneway and match the addressbook
+
+2003-09-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_object_component):
+ added case for getting the individual recurrences if 'rid' is
+ not NULL,
+
+2003-09-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_object_sexp): expand recurrences
+ for recurrent objects.
+ (match_recurrence_sexp): add the recurrences that match the query
+ expression to the object list.
+
+2003-09-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: don't store all recurrences in the
+ private structure.
+
+2003-09-04 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): dont expand recurrences,
+ since they are now expanded by the backends.
+
+2003-09-02 JP Rosevear <jpr@ximian.com>
+
+ * gui/tasks-control.c (sensitize_commands): adapt to cal-client
+ threaded sync api changes
+
+ * gui/itip-utils.c (itip_organizer_is_user): ditto
+
+ * gui/gnome-cal.c (gnome_calendar_purge): ditto
+
+ * gui/e-meeting-model.c (process_section): ditto
+
+ * gui/e-calendar-table.c (e_calendar_table_show_popup_menu): ditto
+
+ * gui/e-cal-view.c (e_cal_view_create_popup_menu): ditto
+
+ * gui/calendar-commands.c (sensitize_calendar_commands): ditto
+ (sensitize_taskpad_commands): ditto
+
+ * gui/dialogs/task-editor.c (set_menu_sens): ditto
+
+ * gui/dialogs/meeting-page.c (meeting_page_construct): ditto
+
+ * gui/dialogs/event-editor.c (set_menu_sens): ditto
+
+ * gui/dialogs/alarm-page.c (add_clicked_cb): ditto
+
+ * conduits/calendar/calendar-conduit.c (pre_sync): convert to
+ cal_client api changes
+
+ * conduits/todo/todo-conduit.c (pre_sync): ditto
+
+ * cal-client/client-test.c (list_uids): match new error handling
+
+ * cal-client/cal-marshal.list: marshallers
+
+ * cal-client/cal-listener.[hc]: emit signals for corba listener
+ callbacks - start with is_read_only, get_static_capabilities,
+ get_cal_address, get_ldap_attribute, open, remove and object_list
+
+ * cal-client/cal-client.h: move the status enum away from here,
+ update protos to new thread sync api standard
+
+ * cal-client/cal-client.c: the listener emits signals instead of
+ using callback functions now and we return booleans + GError in
+ outs for results
+ (e_calendar_error_quark): for GError handling
+ (cal_read_only_cb): handle listener op callback
+ (cal_cal_address_cb): ditto
+ (cal_alarm_address_cb): ditto
+ (cal_ldap_attribute_cb): ditto
+ (cal_static_capabilities_cb): ditto
+ (cal_opened_cb): ditto
+ (cal_removed_cb): ditto
+ (cal_object_list_cb): ditto
+
+ * cal-client/cal-client-types.h: add GError stuff
+
+ * cal-client/Makefile.am: build glib marshal stuff
+
+ * pcs/query.c (backend_opened_cb): comment out some break
+ temporarily
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_open): just call the backend method, it will
+ handle the notification
+ (impl_Cal_remove): ditto
+ (impl_Cal_isReadOnly): ditto
+ (impl_Cal_getCalAddress): ditto
+ (impl_Cal_getAlarmEmailAddress): ditto
+ (impl_Cal_getLdapAttribute): ditto
+ (impl_Cal_getStaticCapabilities): ditto
+ (impl_Cal_getObjectList): simplify
+ (cal_new): set poa to be threaded
+ (cal_notify_read_only): notification utils
+ (cal_notify_cal_address): ditto
+ (cal_notify_alarm_email_address): ditto
+ (cal_notify_ldap_attribute): ditto
+ (cal_notify_static_capabilities): ditto
+ (cal_notify_open): ditto
+ (cal_notify_remove): ditto
+ (cal_notify_object_list): ditto
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): dup the key and the
+ object
+ (cal_factory_new): set poa to be threaded
+
+ * pcs/cal-backend.h: update vmethods and protos
+
+ * pcs/cal-backend.c (cal_backend_get_cal_address): we no longer
+ return anything - the callee is responsible for notification
+ (cal_backend_get_alarm_email_address): ditto
+ (cal_backend_get_ldap_attribute): ditto
+ (cal_backend_get_static_capabilities): ditto
+ (cal_backend_open): ditto
+ (cal_backend_remove): ditto
+
+ * pcs/cal-backend-file.h: update inheritance
+
+ * pcs/cal-backend-file.c: inherit from CalBackendSync and make
+ is_read_only, get_static_capabilities, get_cal_address, get_ldap_attribute, open and
+ remove match
+
+ * pcs/Makefile.am: build new files
+
+2003-09-02 JP Rosevear <jpr@ximian.com>
+
+ * idl/evolution-calendar.idl: make all listener callbacks one ways
+
+2003-09-02 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp, match_object_sexp):
+ new callbacks for g_hash_table_foreach in get_object_list.
+ (cal_backend_file_get_object_list): don't use the priv->comp list
+ to check the components, use the hash table, which contains all
+ the recurrences already expanded.
+ (add_component): only expand recurrences for recurrent components.
+
2003-09-01 Andrew Wu <Yang.Wu@sun.com>
- * gui/e-day-view.c:
- (e_day_view_change_event_end_time_up):
- (e_day_view_change_event_end_time_down):
- Use "ctrl+shift+alt+Up/Down" to change the end time of the editing event.
+ * gui/e-day-view.c:
+ (e_day_view_change_event_end_time_up):
+ (e_day_view_change_event_end_time_down): Use
+ "ctrl+shift+alt+Up/Down" to change the end time of the editing
+ event.
+
+2003-08-29 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (lookup_component): take into account the 'rid'
+ argument.
+ (get_rid_string): new function to convert the recurrence ID to string.
+ (add_recurrence_to_object): callback for cal_recur_generate_instances.
+ (add_component): expand recurrences and g_strdup the hash's key.
+ (free_cal_component): free also the hash's key.
+
2003-08-28 Hans Petter Jansson <hpj@ximian.com>
* gui/alarm-notify/alarm-queue.c (tray_icon_blink_cb)
@@ -243,6 +1852,72 @@
* gui/alarm-notify/alarm-notify.c (AlarmNotify_removeCalendar): set
the initial value of lc_ptr and orig_str_ptr to NULL to avoid crash.
+
+2003-08-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: QueryListener::notifyObjUpdated now gets
+ a sequence of CalObj's.
+
+ * pcs/query.c (add_component): send the whole object to the listener,
+ not just the UID. Improved the way the listeners are notified, by allocating
+ a CORBA sequence to be used for all listeners, not one for each.
+ (match_component): pass the CalComponent to add_component, not only the UID.
+ (start_cached_query_cb): send the whole object to the listener.
+
+ * cal-client/cal-query.[ch]: changed argument names for "obj_updated"
+ signal.
+ (obj_updated_cb): pass the calobj's, not uid's.
+
+ * gui/e-tasks.c (query_obj_updated_cb):
+ * gui/gnome-cal.c (dn_query_obj_updated_cb, purging_obj_updated_cb):
+ * gui/e-cal-model.c (query_obj_updated_cb): we now get the object's
+ string representation instead of the UID.
+
+2003-08-25 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_object): added a 'rid' argument
+ to match the IDL method.
+
+ * conduits/calendar/calendar-conduit.c (local_record_from_uid):
+ * conduits/todo/todo-conduit.c (local_record_from_uid):
+ * gui/comp-editor-factory.c (edit_existing):
+ * gui/comp-util.c (cal_comp_is_on_server):
+ * gui/e-cal-model.c (query_obj_updated_cb):
+ * gui/e-itip-control.c (find_server, get_real_item, update_attendee_status):
+ * gui/gnome-cal.c (dn_query_obj_updated_cb, purging_obj_updated_cb):
+ * gui/dialogs/comp-editor.c (obj_updated_cb): adapted to changes in
+ cal_client_get_object().
+
+2003-08-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query-backend.c (object_updated_cb):
+ * pcs/cal-backend.c (cal_backend_get_type_by_uid): use 'rid' parameter
+ where appropriate.
+
+ * pcs/cal-backend-file.c (check_dup_uid): removed unused variables.
+ (cal_backend_file_compute_changes_foreach_key): pass a NULL 'rid'
+ to cal_backend_get_object().
+ (lookup_component): get a 'rid' argument also.
+ (cal_backend_file_cancel_object, cal_backend_file_remove_object):
+ pass correct number of parameters to lookup_component().
+
+2003-08-22 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: use UID/RID pairs to identify objects.
+
+ * pcs/cal.c (impl_Cal_getObject): added 'rid' parameter.
+
+ * pcs/cal-backend.c (cal_backend_get_object): added 'rid' parameter.
+ (cal_backend_get_object_component): ditto.
+ (get_object): ditto.
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_object_component):
+ added 'rid' parameter.
+ (lookup_component): added 'rid' parameter and made it search for the
+ recurrence when that parameter is not NULL.
+ (cal_backend_file_get_alarms_for_object, cal_backend_file_update_object):
+ adapted to changes in lookup_component().
+
2003-08-22 Frederic Crozat <fcrozat@mandrakesoft.com>
* gui/alarm-notify/notify-main.c: (main):
@@ -300,6 +1975,111 @@
(gnome_calendar_get_search_bar_widget),
(gnome_calendar_get_view_notebook_widget): new functions
+
+2003-08-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query-backend.c (foreach_uid_cb): use the icalcomponent
+ to call icalcomponent_get_uid, not the string.
+
+2003-08-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: store objects by UID and RID.
+ (free_object): new function to free the CalBackendFileObject structure.
+ (cal_backend_file_dispose): use free_object callback to remove the
+ objects in the comp_uid_hash.
+ (lookup_component): search correctly the component in the new hash
+ table organizarion.
+ (check_dup_uid): ditto.
+ (add_component): ditto.
+ (remove_component): ditto.
+
+2003-08-19 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (setup_widgets): set up models here
+ (gnome_calendar_construct): not here
+
+ * conduits/calendar/calendar-conduit.c
+ (e_calendar_context_destroy): we have a list of calcomponents
+ rather than uids now
+ (process_multi_day): build a list of components rather than uids
+ (pre_sync): use get_object_list instead of getting uids
+ (for_each): create local records from calcomponents
+
+ * conduits/todo/todo-conduit.c: as above
+
+ * gui/print.c (instance_cb): mark as true if we found an instance
+ (print_month_small): see if atleast one instance exists in a
+ slight different way
+
+ * cal-client/client-test.c (list_uids): use get_object_list
+
+ * cal-client/cal-listener.h: update protos
+
+ * cal-client/cal-listener.c (cal_listener_class_init): set object
+ list callback implementation
+ (impl_notifyObjectListRequested): implement
+ (cal_listener_construct): take object list callback function
+ (cal_listener_new): ditto
+
+ * cal-client/cal-client.h: update protos, add status
+
+ * cal-client/cal-client.c (e_calendar_new_op): create new op
+ (e_calendar_get_op): retrieve current op
+ (e_calendar_free_op): free the op
+ (e_calendar_remove_op): clear current op
+ (cal_client_init): create new mutex
+ (cal_client_finalize): destroy mutex
+ (build_object_list): build list of icalcomponents
+ (cal_object_list_cb): handle getObjectList response
+ (real_open_calendar): pass extra listener arg
+ (cal_client_get_object_list): implement using thread safe mutex
+ locking
+ (cal_client_get_object_list_as_comp): return calcomponents instead
+ of icalcomponents
+ (cal_client_generate_instances): just get the object list - no
+ need to make it atomic since get_object_list is already atomic
+
+ * pcs/query.c (query_finalize): free new sexp class
+ (parse_sexp): use new sexp class
+ (match_component): ditto
+
+ * pcs/query-backend.c (foreach_uid_cb): use icalcomponent to
+ extract uid
+ (query_backend_new): get all objects using object list call
+
+ * pcs/cal.c (impl_Cal_getObjectList): implement
+ (cal_class_init): adjust for idl method changes
+
+ * pcs/cal-backend.h: update vmethods, add proto
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove get_uids and
+ get_objects_in_range vmethods, add get_object_list vmethod
+ (cal_backend_get_object_list): call through to vmethod implementation
+
+ * pcs/cal-backend-object-sexp.[hc]: nice class to represent a sexp
+ and search cal components
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): remove
+ get_uids and get_objects_in_range calls and set get_object_list
+ call
+ (cal_backend_file_get_object_list): implement
+ (create_user_free_busy): use sexp ops to implement
+ (cal_backend_file_compute_changes): just iterate over the
+ component list rather than fetching uids
+
+ * pcs/Makefile.am: build new files
+
+ * idl/evolution-calendar.idl: make opening a oneway call, add
+ getObjectList call, remove getUIDS and getObjectsInRange call -
+ both can be done with getObjectList; make listener callbacks
+ oneway
+
+2003-08-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_purge): don't leak the client list.
+ (gnome_calendar_destroy): disconnect from all callbacks on all
+ loaded clients.
+
2003-08-19 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model-tasks.c (ecmt_get_color_for_component): use
@@ -321,6 +2101,51 @@
* gui/e-week-view.c (e_week_view_add_event, e_week_view_do_key_press):
same as e-day-view.c
+2003-08-18 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/calendar-component.c (impl_createControls): Oops, pass
+ [NULL, NULL] to gtk_scrolled_window_new().
+
+2003-08-18 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/main.c (factory): Ref the object from
+ calendar_component_peek() before returning it.
+
+2003-08-17 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/control-factory.h: #include <bonobo/bonobo-control.h>.
+
+ * gui/Makefile.am (libevolution_calendar_la_LIBADD): Link to
+ libeutil.
+
+ * gui/e-calendar-table.c (e_calendar_table_set_status_message):
+ Don't use the global_shell_client.
+
+ * gui/main.c (factory): Call calendar_component_peek() for the
+ GNOME_Evolution_Calendar_Component OAFIID.
+
+ * gui/GNOME_Evolution_Calendar.server.in.in: Set up the
+ GNOME_Evolution_Calendar_Component server and rename
+ GNOME_Evolution_Calendar_Factory to
+ GNOME_Evolution_Calendar_Factory_2.
+ * gui/main.c: Updated IDs accordingly.
+
+ * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct):
+ Use calendar_component_peek_config_directory() instead of
+ evolution_dir.
+ * gui/gnome-cal.c (setup_widgets): Likewise.
+ (gnome_calendar_destroy): Likewise.
+ * gui/dialogs/meeting-page.c (meeting_page_construct): Likewise.
+
+ * gui/gnome-cal.c (gnome_calendar_open): #if 0 some code for
+ figuring out where the task list is.
+
+ * gui/calendar-component.c: New file.
+ * gui/calendar-component.h: New file.
+
+ * gui/itip-utils.c (itip_addresses_get): Unref the GConf client
+ from gconf_client_get_default.
+
2003-08-15 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model.c (ecm_get_color_for_component): use tigert's
@@ -341,16 +2166,6 @@
2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
- * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
- use the default client to call cal_comp_*_new_with_defaults, and
- if no client is available, just create an empty icalcomponent.
-
- * gui/e-cal-view.c (e_cal_view_init): create an empty model.
-
- * gui/e-week-view.c (e_week_view_add_event): use the event's client.
-
-2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
-
* gui/e-cal-model.[ch] (e_cal_model_free_component_data): new
function.
@@ -367,6 +2182,46 @@
e_week_view_update_event_cb, e_week_view_remove_event_cb,
e_week_view_free_events): same as EDayView.
+2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ use the default client to call cal_comp_*_new_with_defaults, and
+ if no client is available, just create an empty icalcomponent.
+
+ * gui/e-cal-view.c (e_cal_view_init): create an empty model.
+
+ * gui/e-week-view.c (e_week_view_add_event): use the event's client.
+
+2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_open): unref the client if there
+ is an error.
+ (update_query): set status bar messages for progress.
+ (update_query_timeout): re-enabled.
+ (client_cal_opened_cb): install timeout handler for the query updates.
+
+ * gui/e-cal-view.c (e_cal_view_set_model): connect to all appropriate
+ signals on the model, to be called for every change.
+ (model_row_changed_cb, model_rows_changed_cb): new model callbacks.
+
+ * gui/e-week-view-event-item.c (e_week_view_event_item_draw): colorize
+ the background for multiple days events.
+
+2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (ecm_append_row, ecm_get_color_for_component):
+ * gui/e-cal-model-tasks.c (ecmt_get_color_for_component): merged
+ missing bith from calendar-views-with-model branch.
+
+2003-08-13 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.c (real_open_calendar): set the priv->cal
+ pointer in a slightly different spot so we have it in the call
+ back
+
+ * gui/e-cal-model.c (e_cal_model_get_client_list): merge this in
+ properly
+
2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model.c (ecm_get_color_for_component): assign the colors
@@ -393,7 +2248,170 @@
* gui/e-week-view-event-item.c (e_week_view_event_item_draw): colorize
the background for multiple days events.
+
+2003-08-13 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (create_client): there is no more
+ object updated signal
+
+ * cal-client/cal-listener.c: clean up comment
+
+ * cal-client/cal-client.c (cal_client_class_init): remove
+ obj_updated and obj_removed signals
+
+ * cal-client/cal-client.h: ditto
+
+2003-08-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.h: remove get_uri vmethod
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove get_uri
+ vmethod init
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): no longer
+ a get uri vmethod
+ (cal_backend_file_get_uri): remove implementation of above
+
+2003-08-12 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (main): use tmp uris
+
+ * cal-client/cal-listener.h: update protos
+
+ * cal-client/cal-listener.c (cal_listener_init): init removed
+ function
+ (cal_listener_finalize): clear removed function
+ (impl_notifyCalOpened): take file status
+ (impl_notifyCalRemoved): implement
+ (cal_listener_construct): take remove function arg
+ (cal_listener_new): ditto
+
+ * cal-client/cal-client.h: update protos, add remove status
+
+ * cal-client/cal-client.c
+ (cal_client_remove_status_enum_get_type): add remove status type
+ (cal_client_class_init): add removed signal
+ (cal_opened_cb): can no longer get unsupported exception here
+ (cal_removed_cb): emit removed status
+ (real_open_calendar): pass removed callback function to listener
+ (get_fall_back_uri): no longer append tasks.ics or calendar.ics
+ (cal_client_remove_calendar): new c wrapper for corba function -
+ calendar must be open currently
+
+ * pcs/query.c (backend_opened_cb): only disconnect the open
+ callback
+ (backend_removed_cb): handle calendar removal
+ (query_construct): listen for remove signal as well
+
+ * pcs/cal.h: cal no longer takes uri during construction
+
+ * pcs/cal.c (backend_to_listener_status): convert backend to corba
+ status code
+ (impl_Cal_open): backend open no longer takes uri, use above to
+ send back status
+ (impl_Cal_remove): implement
+ (cal_construct): we no longer track the uri
+ (cal_finalize): ditto
+ (cal_class_init): set remove epv method
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): instantiate backend
+ with uri and kind properties
+
+ * pcs/cal-backend.h: list file status enum, add protos
+
+ * pcs/cal-backend.c (cal_backend_set_property): implement object
+ properties
+ (cal_backend_get_property): ditto
+ (cal_backend_class_init): add properties vmethods and uri, kind
+ properties, removed signal
+ (cal_backend_get_uri): don't get the uri from the backend
+ (cal_backend_get_kind): get the kind from the backend
+ (cal_backend_open): adapt to new open call, no uri passed in
+ (cal_backend_remove): call through to remove implementation
+ (cal_backend_opened): use new file status
+ (cal_backend_removed): emit removed signal
+
+ * pcs/cal-backend-file.h: update protos
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): override
+ remove vmethod
+ (cal_backend_file_init): default file name to calendar.ics
+ (cal_backend_file_set_file_name): accessor for filename tacked on
+ to uri
+ (cal_backend_file_get_file_name): ditto
+ (open_cal): return "file" type status codes
+ (create_cal): ditto
+ (get_uri_string): construct the full uri string
+ (cal_backend_file_open): use above
+ (cal_backend_file_remove): implement
+
+ * pcs/cal-backend-file-todos.c (cal_backend_file_todos_init): set
+ the file name to tasks.ics
+
+ * pcs/cal-backend-file-events.c (cal_backend_file_events_init):
+ set the file name to calendar.ics
+
+ * cal-util/cal-util.c (cal_util_expand_uri): just return a copy of
+ the uri now
+
+ * idl/evolution-calendar.idl: convert OpenStatus to FileStatus so
+ remove() can use it as well
+
+ * gui/gnome-cal.c (gnome_calendar_open): just open the default
+ folder in all cases
+
+2003-08-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-util/cal-util.[ch] (cal_util_component_has_alarms): new function.
+
+ * gui/gnome-cal.[ch]:
+ * gui/goto.c:
+ * gui/itip-bonobo-control.c:
+ * gui/print.c:
+ * gui/e-week-view.[ch]:
+ * gui/e-day-view.[ch]: lots of fixes to make all compile with no
+ warnings.
+
+2003-08-12 Rodrigo Moya <rodrigo@ximian.com>
+ * cal-util/cal-util.[ch] (cal_util_component_has_organizer):
+ new function.
+
+ * gui/e-day-view-main-item.c:
+ * gui/e-day-view-top-item.c:
+ * gui/e-week-view-event-item.c:
+ * gui/e-week-view.c: adaptated to changes in ECalViewEvent.
+
+ * gui/e-cal-model.[ch] (e_cal_model_get_client_list): new function.
+ (ecm_append_row): fixed usage of icalcomponent variable.
+
+ * gui/e-cal-view.c (e_cal_view_class_init): removed unused variable.
+ (selection_received): use default client for pasting from clipboard.
+ (e_cal_view_cut_clipboard): cut the appointment from its client.
+ (e_cal_view_copy_clipboard, delete_event, on_save_as, om_print_event,
+ e_cal_view_delete_selected_occurrence, on_meeting, on_forward,
+ e_cal_view_create_popup_menu): adapted to changes in ECalViewEvent.
+ (e_cal_view_delete_selected_event, e_cal_view_delete_selected_events):
+ pass the ECalViewEvent to delete_event, so that it knows which
+ CalClient to use.
+ (on_edit_appointment): pass CalClient and icalcomponent to
+ gnome_calendar_edit_object.
+ (on_publish): publish F/B info for all the clients currently loaded
+ in the view.
+ (setup_popup_icons): added missing argument to gtk_image_new_from_stock.
+
+ * gui/calendar-commands.c (publish_freebusy_cmd): publish F/B info
+ for all the clients currently loaded in the view.
+ (sensitize_calendar_commands): use icalcomponent functions.
+
+ * gui/e-day-view.c:
+ * gui/comp-editor-factory.c (impl_editExisting):
+ * gui/calendar-offline-handler.c (backend_cal_opened_online):
+ * gui/e-alarm-list.c (e_alarm_list_finalize):
+ * gui/e-cal-model-tasks.c (ecmt_get_color_for_component):
+ * gui/e-date-time-list.c (e_date_time_list_finalize):
+ * gui/control-factory.c (get_prop): fixed warnings.
+
2003-08-12 Hans Petter Jansson <hpj@ximian.com>
* gui/calendar-offline-handler.c (impl_dispose): Chain. Prevent
@@ -799,6 +2817,27 @@
* cal-client/cal-client-multi.[ch]:
* cal-client/Makefile.am: removed obsolete code.
+2003-07-30 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/main.c (factory): Do not depend on global_shell_client being
+ not NULL for creating the calendar preferences dialog.
+
+ * gui/e-itip-control.c (show_current): Don't call get_servers
+ anymore [to be fixed].
+ (get_servers): #if 0ed out.
+ (object_requested_cb): Don't create the folder selector button.
+
+ * gui/e-cal-view.c (e_cal_view_set_status_message): Don't create
+ an activity client.
+
+ * gui/calendar-model.c (calendar_model_set_status_message): Don't
+ create an activity client.
+
+ * gui/calendar-component.c: Removed global variable
+ global_shell_client.
+ (owner_set_cb): Don't set global_shell_client.
+ (owner_unset_cb): Don't set it here either.
+
2003-07-29 Rodrigo Moya <rodrigo@ximian.com>
Fixes all "alarm daemon doesn't start with session"
diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore
index 1537e6e01d..f2aa4f92ae 100644
--- a/calendar/cal-client/.cvsignore
+++ b/calendar/cal-client/.cvsignore
@@ -10,6 +10,8 @@ evolution-calendar.h
evolution-calendar-common.lo
evolution-calendar-skels.lo
evolution-calendar-stubs.lo
+cal-marshal.c
+cal-marshal.h
*.lo
*.la
client-test
diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am
index 5e48e7db23..5f8b5a3cf1 100644
--- a/calendar/cal-client/Makefile.am
+++ b/calendar/cal-client/Makefile.am
@@ -38,6 +38,8 @@ libcal_clientincludedir = $(privincludedir)/cal-client
libcal_client_la_SOURCES = \
$(CORBA_GENERATED_C) \
cal-client-types.c \
+ cal-marshal.c \
+ cal--marshal.h \
cal-client.c \
cal-listener.c \
cal-listener.h \
@@ -72,7 +74,10 @@ client_test_LDADD = \
libcal-client.la \
$(EVOLUTION_CALENDAR_LIBS)
-BUILT_SOURCES = $(CORBA_GENERATED)
+MARSHAL_GENERATED = cal-marshal.c cal-marshal.h
+@EVO_MARSHAL_RULE@
+
+BUILT_SOURCES = $(CORBA_GENERATED) $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
dist-hook:
diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h
index c160a1fa94..925628337b 100644
--- a/calendar/cal-client/cal-client-types.h
+++ b/calendar/cal-client/cal-client-types.h
@@ -29,6 +29,10 @@ G_BEGIN_DECLS
+#define E_CALENDAR_ERROR e_calendar_error_quark()
+
+GQuark e_calendar_error_quark (void) G_GNUC_CONST;
+
typedef enum {
CAL_CLIENT_CHANGE_ADDED = 1 << 0,
CAL_CLIENT_CHANGE_MODIFIED = 1 << 1,
@@ -41,6 +45,28 @@ typedef struct
CalClientChangeType type;
} CalClientChange;
+typedef enum {
+ E_CALENDAR_STATUS_OK,
+ E_CALENDAR_STATUS_INVALID_ARG,
+ E_CALENDAR_STATUS_BUSY,
+ E_CALENDAR_STATUS_REPOSITORY_OFFLINE,
+ E_CALENDAR_STATUS_NO_SUCH_CALENDAR,
+ E_CALENDAR_STATUS_OBJECT_NOT_FOUND,
+ E_CALENDAR_STATUS_INVALID_OBJECT,
+ E_CALENDAR_STATUS_URI_NOT_LOADED,
+ E_CALENDAR_STATUS_URI_ALREADY_LOADED,
+ E_CALENDAR_STATUS_PERMISSION_DENIED,
+ E_CALENDAR_STATUS_CARD_NOT_FOUND,
+ E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS,
+ E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED,
+ E_CALENDAR_STATUS_CANCELLED,
+ E_CALENDAR_STATUS_COULD_NOT_CANCEL,
+ E_CALENDAR_STATUS_AUTHENTICATION_FAILED,
+ E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION,
+ E_CALENDAR_STATUS_OTHER_ERROR
+} ECalendarStatus;
+
void cal_client_change_list_free (GList *list);
G_END_DECLS
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
index e40d405120..95efdd6d5d 100644
--- a/calendar/cal-client/cal-client.c
+++ b/calendar/cal-client/cal-client.c
@@ -22,20 +22,39 @@
#include <config.h>
#endif
+#include <pthread.h>
#include <string.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-i18n.h>
#include <libgnome/gnome-util.h>
#include "e-util/e-component-listener.h"
#include "e-util/e-config-listener.h"
+#include "e-util/e-url.h"
+#include "e-util/e-msgport.h"
#include "cal-util/cal-util-marshal.h"
-#include "cal-client-types.h"
+#include "cal-util/timeutil.h"
#include "cal-client.h"
#include "cal-listener.h"
+#include "query-listener.h"
+typedef struct {
+ EMutex *mutex;
+ pthread_cond_t cond;
+ ECalendarStatus status;
+
+ char *uid;
+ GList *list;
+ gboolean bool;
+ char *string;
+
+ CalQuery *query;
+ QueryListener *listener;
+} ECalendarOp;
+
/* Private part of the CalClient structure */
struct _CalClientPrivate {
/* Load state to avoid multiple loads */
@@ -45,7 +64,12 @@ struct _CalClientPrivate {
* NULL if we are not loaded.
*/
char *uri;
+ CalObjType type;
+
+ ECalendarOp *current_op;
+ EMutex *mutex;
+
/* Email address associated with this calendar, or NULL */
char *cal_address;
char *alarm_email_address;
@@ -85,8 +109,6 @@ struct _CalClientPrivate {
enum {
CAL_OPENED,
CAL_SET_MODE,
- OBJ_UPDATED,
- OBJ_REMOVED,
BACKEND_ERROR,
CATEGORIES_CHANGED,
FORGET_PASSWORD,
@@ -94,10 +116,6 @@ enum {
LAST_SIGNAL
};
-static void cal_client_class_init (CalClientClass *klass);
-static void cal_client_init (CalClient *client, CalClientClass *klass);
-static void cal_client_finalize (GObject *object);
-
static void cal_client_get_object_timezones_cb (icalparameter *param,
void *data);
@@ -105,36 +123,28 @@ static guint cal_client_signals[LAST_SIGNAL];
static GObjectClass *parent_class;
+#define E_CALENDAR_CHECK_STATUS(status,error) G_STMT_START{ \
+ if ((status) == E_CALENDAR_STATUS_OK) { \
+ return TRUE; \
+ } \
+ else { \
+ const char *msg; \
+ msg = cal_client_get_error_message ((status)); \
+ g_set_error ((error), E_CALENDAR_ERROR, (status), msg, (status)); \
+ return FALSE; \
+ } }G_STMT_END
+
-/**
- * cal_client_get_type:
- *
- * Registers the #CalClient class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalClient class.
- **/
-GType
-cal_client_get_type (void)
+/* Error quark */
+GQuark
+e_calendar_error_quark (void)
{
- static GType cal_client_type = 0;
-
- if (!cal_client_type) {
- static GTypeInfo info = {
- sizeof (CalClientClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_client_class_init,
- NULL, NULL,
- sizeof (CalClient),
- 0,
- (GInstanceInitFunc) cal_client_init
- };
- cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
- }
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("e-calendar-error-quark");
- return cal_client_type;
+ return q;
}
GType
@@ -198,118 +208,48 @@ cal_mode_enum_get_type (void)
return cal_mode_enum_type;
}
-/* Class initialization function for the calendar client */
-static void
-cal_client_class_init (CalClientClass *klass)
+/* EBookOp calls */
+
+static ECalendarOp*
+e_calendar_new_op (CalClient *client)
{
- GObjectClass *object_class;
+ ECalendarOp *op = g_new0 (ECalendarOp, 1);
- object_class = (GObjectClass *) klass;
+ op->mutex = e_mutex_new (E_MUTEX_SIMPLE);
+ pthread_cond_init (&op->cond, 0);
- parent_class = g_type_class_peek_parent (klass);
-
- cal_client_signals[CAL_OPENED] =
- g_signal_new ("cal_opened",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_opened),
- NULL, NULL,
- g_cclosure_marshal_VOID__ENUM,
- G_TYPE_NONE, 1,
- CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
- cal_client_signals[CAL_SET_MODE] =
- g_signal_new ("cal_set_mode",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_ENUM,
- G_TYPE_NONE, 2,
- CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
- CAL_MODE_ENUM_TYPE);
- cal_client_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_ERROR] =
- g_signal_new ("backend_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[CATEGORIES_CHANGED] =
- g_signal_new ("categories_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, categories_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
- cal_client_signals[FORGET_PASSWORD] =
- g_signal_new ("forget_password",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, forget_password),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_DIED] =
- g_signal_new ("backend_died",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_died),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ client->priv->current_op = op;
- klass->cal_opened = NULL;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->categories_changed = NULL;
- klass->forget_password = NULL;
- klass->backend_died = NULL;
+ return op;
+}
- object_class->finalize = cal_client_finalize;
+static ECalendarOp*
+e_calendar_get_op (CalClient *client)
+{
+ if (!client->priv->current_op) {
+ g_warning (G_STRLOC ": Unexpected response");
+ return NULL;
+ }
+
+ return client->priv->current_op;
}
-/* Object initialization function for the calendar client */
static void
-cal_client_init (CalClient *client, CalClientClass *klass)
+e_calendar_free_op (ECalendarOp *op)
{
- CalClientPrivate *priv;
+ /* XXX more stuff here */
+ pthread_cond_destroy (&op->cond);
+ e_mutex_destroy (op->mutex);
+ g_free (op);
+}
- priv = g_new0 (CalClientPrivate, 1);
- client->priv = priv;
+static void
+e_calendar_remove_op (CalClient *client, ECalendarOp *op)
+{
+ if (client->priv->current_op != op)
+ g_warning (G_STRLOC ": Cannot remove op, it's not current");
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- priv->uri = NULL;
- priv->cal_address = NULL;
- priv->alarm_email_address = NULL;
- priv->ldap_attribute = NULL;
- priv->capabilities = FALSE;
- priv->factories = NULL;
- priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
- priv->default_zone = icaltimezone_get_utc_timezone ();
- priv->comp_listener = NULL;
+ client->priv->current_op = NULL;
}
/* Gets rid of the factories that a client knows about */
@@ -364,7 +304,7 @@ destroy_cal (CalClient *client)
CORBA_exception_init (&ev);
result = CORBA_Object_is_nil (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("destroy_cal(): could not see if the "
+ g_message (G_STRLOC ": could not see if the "
"calendar client interface object was nil");
priv->cal = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
@@ -375,19 +315,7 @@ destroy_cal (CalClient *client)
if (result)
return;
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_unref (priv->cal, &ev);
- if (BONOBO_EX (&ev))
- g_message ("destroy_cal(): could not unref the calendar client interface object");
-
- CORBA_exception_free (&ev);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (priv->cal, &ev);
- if (BONOBO_EX (&ev))
- g_message ("destroy_cal(): could not release the calendar client interface object");
-
- CORBA_exception_free (&ev);
+ bonobo_object_release_unref (priv->cal, NULL);
priv->cal = CORBA_OBJECT_NIL;
}
@@ -400,184 +328,541 @@ free_timezone (gpointer key, gpointer value, gpointer data)
icaltimezone_free (value, TRUE);
}
-/* Finalize handler for the calendar client */
+
+
static void
-cal_client_finalize (GObject *object)
+backend_died_cb (EComponentListener *cl, gpointer user_data)
{
- CalClient *client;
CalClientPrivate *priv;
+ CalClient *client = (CalClient *) user_data;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_CLIENT (object));
+ g_return_if_fail (IS_CAL_CLIENT (client));
- client = CAL_CLIENT (object);
priv = client->priv;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+}
- if (priv->listener) {
- cal_listener_stop_notification (priv->listener);
- bonobo_object_unref (priv->listener);
- priv->listener = NULL;
+/* Signal handlers for the listener's signals */
+/* Handle the cal_opened notification from the listener */
+
+static void
+cal_read_only_cb (CalListener *listener, ECalendarStatus status, gboolean read_only, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->comp_listener) {
- g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL,
- client);
- g_object_unref (G_OBJECT (priv->comp_listener));
- priv->comp_listener = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->bool = read_only;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_cal_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- destroy_factories (client);
- destroy_cal (client);
+ e_mutex_lock (op->mutex);
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ op->status = status;
+ op->string = g_strdup (address);
- if (priv->uri) {
- g_free (priv->uri);
- priv->uri = NULL;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_alarm_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->cal_address) {
- g_free (priv->cal_address);
- priv->cal_address = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (address);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_ldap_attribute_cb (CalListener *listener, ECalendarStatus status, const char *attribute, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->alarm_email_address) {
- g_free (priv->alarm_email_address);
- priv->alarm_email_address = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (attribute);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_static_capabilities_cb (CalListener *listener, ECalendarStatus status, const char *capabilities, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->ldap_attribute) {
- g_free (priv->ldap_attribute);
- priv->ldap_attribute = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (capabilities);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_opened_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->capabilities) {
- g_free (priv->capabilities);
- priv->capabilities = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_hash_table_foreach (priv->timezones, free_timezone, NULL);
- g_hash_table_destroy (priv->timezones);
- priv->timezones = NULL;
+ e_mutex_lock (op->mutex);
- g_free (priv);
- client->priv = NULL;
+ op->status = status;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-
+static void
+cal_object_created_cb (CalListener *listener, ECalendarStatus status, const char *uid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (uid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
+cal_object_modified_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClientPrivate *priv;
- CalClient *client = (CalClient *) user_data;
+ CalClient *client = data;
+ ECalendarOp *op;
- g_return_if_fail (IS_CAL_CLIENT (client));
+ op = e_calendar_get_op (client);
- priv = client->priv;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-/* Signal handlers for the listener's signals */
-/* Handle the cal_opened notification from the listener */
static void
-cal_opened_cb (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data)
+cal_object_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClient *client;
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_Cal cal_copy;
- CalClientOpenStatus client_status;
+ CalClient *client = data;
+ ECalendarOp *op;
- client = CAL_CLIENT (data);
- priv = client->priv;
+ op = e_calendar_get_op (client);
- g_assert (priv->load_state == CAL_CLIENT_LOAD_LOADING);
- g_assert (priv->uri != NULL);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- client_status = CAL_CLIENT_OPEN_ERROR;
+ e_mutex_lock (op->mutex);
- switch (status) {
- case GNOME_Evolution_Calendar_Listener_SUCCESS:
- CORBA_exception_init (&ev);
- cal_copy = CORBA_Object_duplicate (cal, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_opened_cb(): could not duplicate the "
- "calendar client interface");
- CORBA_exception_free (&ev);
- goto error;
- }
- CORBA_exception_free (&ev);
+ op->status = status;
- priv->cal = cal_copy;
- priv->load_state = CAL_CLIENT_LOAD_LOADED;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
- client_status = CAL_CLIENT_OPEN_SUCCESS;
+static void
+cal_alarm_discarded_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- /* setup component listener */
- priv->comp_listener = e_component_listener_new (priv->cal);
- g_signal_connect (G_OBJECT (priv->comp_listener), "component_died",
- G_CALLBACK (backend_died_cb), client);
- goto out;
+ op = e_calendar_get_op (client);
- case GNOME_Evolution_Calendar_Listener_ERROR:
- client_status = CAL_CLIENT_OPEN_ERROR;
- goto error;
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- case GNOME_Evolution_Calendar_Listener_NOT_FOUND:
- client_status = CAL_CLIENT_OPEN_NOT_FOUND;
- goto error;
+ e_mutex_lock (op->mutex);
- case GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED:
- client_status = CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED;
- goto error;
+ op->status = status;
- case GNOME_Evolution_Calendar_Listener_PERMISSION_DENIED :
- client_status = CAL_CLIENT_OPEN_PERMISSION_DENIED;
- goto error;
+ pthread_cond_signal (&op->cond);
- default:
- g_assert_not_reached ();
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_objects_received_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- error:
+ e_mutex_lock (op->mutex);
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
+ op->status = status;
- /* We free the priv->uri and set the priv->load_state until after the
- * "cal_opened" signal has been emitted so that handlers will be able to
- * access this information.
- */
+ pthread_cond_signal (&op->cond);
- out:
+ e_mutex_unlock (op->mutex);
+}
- /* We are *not* inside a signal handler (this is just a simple callback
- * called from the listener), so there is not a temporary reference to
- * the client object. We ref() so that we can safely emit our own
- * signal and clean up.
- */
+static void
+cal_objects_sent_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- g_object_ref (G_OBJECT (client));
+ op = e_calendar_get_op (client);
- g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED],
- 0, client_status);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- if (client_status != CAL_CLIENT_OPEN_SUCCESS) {
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_default_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_assert (priv->load_state != CAL_CLIENT_LOAD_LOADING);
+ e_mutex_lock (op->mutex);
- g_object_unref (G_OBJECT (client));
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_list_cb (CalListener *listener, ECalendarStatus status, GList *objects, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (objects);
+
+ for (l = op->list; l; l = l->next)
+ l->data = icalcomponent_new_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_timezone_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_add_timezone_cb (CalListener *listener, ECalendarStatus status, const char *tzid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (tzid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_set_default_timezone_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_changes_cb (CalListener *listener, ECalendarStatus status, GList *changes, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (changes);
+
+ for (l = op->list; l; l = l->next) {
+ CalClientChange *ccc = l->data, *new_ccc;
+
+ new_ccc = g_new (CalClientChange, 1);
+ new_ccc->comp = cal_component_clone (ccc->comp);
+ new_ccc->type = ccc->type;
+
+ l->data = new_ccc;
+ }
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_free_busy_cb (CalListener *listener, ECalendarStatus status, GList *freebusy, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (freebusy);
+
+ for (l = op->list; l; l = l->next)
+ l->data = cal_component_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_query_cb (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->query = cal_query_new (query, op->listener, client);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
/* Handle the cal_set_mode notification from the listener */
@@ -624,26 +909,6 @@ cal_set_mode_cb (CalListener *listener,
g_object_unref (G_OBJECT (client));
}
-/* Handle the obj_updated signal from the listener */
-static void
-obj_updated_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_UPDATED], 0, uid);
-}
-
-/* Handle the obj_removed signal from the listener */
-static void
-obj_removed_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_REMOVED], 0, uid);
-}
-
/* Handle the error_occurred signal from the listener */
static void
backend_error_cb (CalListener *listener, const char *message, gpointer data)
@@ -678,97 +943,343 @@ categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_Str
-static GList *
-get_factories (void)
+static gboolean
+get_factories (const char *str_uri, GList **factories)
{
- GList *factories = NULL;
GNOME_Evolution_Calendar_CalFactory factory;
Bonobo_ServerInfoList *servers;
- CORBA_Environment ev;
+ EUri *uri;
+ char *query;
int i;
- CORBA_exception_init (&ev);
- servers = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')", NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_message ("Cannot perform OAF query for Calendar servers.");
- CORBA_exception_free (&ev);
- return NULL;
+ /* Determine the protocol and query for factory supporting that */
+ uri = e_uri_new (str_uri);
+ if (!uri) {
+ g_warning (G_STRLOC ": Invalid uri string");
+
+ return FALSE;
}
- if (servers->_length == 0)
- g_warning ("No Calendar servers installed.");
+ query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')"
+ " AND calendar:supported_protocols.has ('%s')", uri->protocol);
+
+
+ servers = bonobo_activation_query (query, NULL, NULL);
+
+ g_free (query);
+ e_uri_free (uri);
+ if (!servers) {
+ g_warning (G_STRLOC ": Unable to query for calendar factories");
+
+ return FALSE;
+ }
+
+ /* Try to activate the servers for the protocol */
for (i = 0; i < servers->_length; i++) {
const Bonobo_ServerInfo *info;
info = servers->_buffer + i;
- factory = (GNOME_Evolution_Calendar_CalFactory)
- bonobo_activation_activate_from_id (info->iid, 0, NULL, &ev);
- if (BONOBO_EX (&ev)) {
-#if 0
- g_warning ("cal_client_construct: Could not activate calendar server %s", info->iid);
- CORBA_free (servers);
- CORBA_exception_free (&ev);
- return NULL;
-#endif
- }
+ g_message (G_STRLOC ": Activating calendar factory (%s)", info->iid);
+ factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
+
+ if (factory == CORBA_OBJECT_NIL)
+ g_warning (G_STRLOC ": Could not activate calendar factory (%s)", info->iid);
else
- factories = g_list_prepend (factories, factory);
+ *factories = g_list_append (*factories, factory);
}
CORBA_free (servers);
- CORBA_exception_free (&ev);
- return factories;
+
+ return TRUE;
+}
+
+/* Object initialization function for the calendar client */
+static void
+cal_client_init (CalClient *client, CalClientClass *klass)
+{
+ CalClientPrivate *priv;
+
+ priv = g_new0 (CalClientPrivate, 1);
+ client->priv = priv;
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ priv->uri = NULL;
+ priv->mutex = e_mutex_new (E_MUTEX_REC);
+ priv->listener = cal_listener_new (cal_set_mode_cb,
+ backend_error_cb,
+ categories_changed_cb,
+ client);
+
+ priv->cal_address = NULL;
+ priv->alarm_email_address = NULL;
+ priv->ldap_attribute = NULL;
+ priv->capabilities = FALSE;
+ priv->factories = NULL;
+ priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->default_zone = icaltimezone_get_utc_timezone ();
+ priv->comp_listener = NULL;
+
+ g_signal_connect (G_OBJECT (priv->listener), "read_only", G_CALLBACK (cal_read_only_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "cal_address", G_CALLBACK (cal_cal_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "alarm_address", G_CALLBACK (cal_alarm_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "ldap_attribute", G_CALLBACK (cal_ldap_attribute_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "static_capabilities", G_CALLBACK (cal_static_capabilities_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "open", G_CALLBACK (cal_opened_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove", G_CALLBACK (cal_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "create_object", G_CALLBACK (cal_object_created_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "modify_object", G_CALLBACK (cal_object_modified_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove_object", G_CALLBACK (cal_object_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "discard_alarm", G_CALLBACK (cal_alarm_discarded_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "receive_objects", G_CALLBACK (cal_objects_received_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "send_objects", G_CALLBACK (cal_objects_sent_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "default_object", G_CALLBACK (cal_default_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object", G_CALLBACK (cal_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object_list", G_CALLBACK (cal_object_list_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_timezone", G_CALLBACK (cal_get_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "add_timezone", G_CALLBACK (cal_add_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "set_default_timezone", G_CALLBACK (cal_set_default_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_changes", G_CALLBACK (cal_get_changes_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_free_busy", G_CALLBACK (cal_get_free_busy_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "query", G_CALLBACK (cal_query_cb), client);
+}
+
+/* Finalize handler for the calendar client */
+static void
+cal_client_finalize (GObject *object)
+{
+ CalClient *client;
+ CalClientPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (object));
+
+ client = CAL_CLIENT (object);
+ priv = client->priv;
+
+ if (priv->listener) {
+ cal_listener_stop_notification (priv->listener);
+ bonobo_object_unref (priv->listener);
+ priv->listener = NULL;
+ }
+
+ if (priv->comp_listener) {
+ g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL,
+ client);
+ g_object_unref (G_OBJECT (priv->comp_listener));
+ priv->comp_listener = NULL;
+ }
+
+ destroy_factories (client);
+ destroy_cal (client);
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->mutex) {
+ e_mutex_destroy (priv->mutex);
+ priv->mutex = NULL;
+ }
+
+ if (priv->cal_address) {
+ g_free (priv->cal_address);
+ priv->cal_address = NULL;
+ }
+ if (priv->alarm_email_address) {
+ g_free (priv->alarm_email_address);
+ priv->alarm_email_address = NULL;
+ }
+ if (priv->ldap_attribute) {
+ g_free (priv->ldap_attribute);
+ priv->ldap_attribute = NULL;
+ }
+ if (priv->capabilities) {
+ g_free (priv->capabilities);
+ priv->capabilities = NULL;
+ }
+
+ g_hash_table_foreach (priv->timezones, free_timezone, NULL);
+ g_hash_table_destroy (priv->timezones);
+ priv->timezones = NULL;
+
+ g_free (priv);
+ client->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar client */
+static void
+cal_client_class_init (CalClientClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ cal_client_signals[CAL_OPENED] =
+ g_signal_new ("cal_opened",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
+ cal_client_signals[CAL_SET_MODE] =
+ g_signal_new ("cal_set_mode",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
+ NULL, NULL,
+ cal_util_marshal_VOID__ENUM_ENUM,
+ G_TYPE_NONE, 2,
+ CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
+ CAL_MODE_ENUM_TYPE);
+ cal_client_signals[BACKEND_ERROR] =
+ g_signal_new ("backend_error",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_error),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[CATEGORIES_CHANGED] =
+ g_signal_new ("categories_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, categories_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+ cal_client_signals[FORGET_PASSWORD] =
+ g_signal_new ("forget_password",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, forget_password),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[BACKEND_DIED] =
+ g_signal_new ("backend_died",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_died),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ klass->cal_opened = NULL;
+ klass->categories_changed = NULL;
+ klass->forget_password = NULL;
+ klass->backend_died = NULL;
+
+ object_class->finalize = cal_client_finalize;
}
/**
- * cal_client_construct:
- * @client: A calendar client.
+ * cal_client_get_type:
*
- * Constructs a calendar client object by contacting all available
- * calendar factories.
+ * Registers the #CalClient class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same object as the @client argument, or NULL if the
- * calendar factory could not be contacted.
+ * Return value: The type ID of the #CalClient class.
**/
-CalClient *
-cal_client_construct (CalClient *client)
+GType
+cal_client_get_type (void)
{
- CalClientPrivate *priv;
+ static GType cal_client_type = 0;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ if (!cal_client_type) {
+ static GTypeInfo info = {
+ sizeof (CalClientClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_client_class_init,
+ NULL, NULL,
+ sizeof (CalClient),
+ 0,
+ (GInstanceInitFunc) cal_client_init
+ };
+ cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
+ }
+ return cal_client_type;
+}
+
+
+static gboolean
+fetch_corba_cal (CalClient *client, const char *str_uri, CalObjType type)
+{
+ CalClientPrivate *priv;
+ GList *f;
+ CORBA_Environment ev;
+
priv = client->priv;
- priv->factories = get_factories ();
+ g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
+ g_assert (priv->uri == NULL);
- return client;
+ g_return_val_if_fail (str_uri != NULL, FALSE);
+
+ if (!get_factories (str_uri, &priv->factories))
+ return FALSE;
+
+ priv->uri = g_strdup (str_uri);
+ priv->type = type;
+
+ for (f = priv->factories; f; f = f->next) {
+ GNOME_Evolution_Calendar_Cal cal;
+
+ CORBA_exception_init (&ev);
+
+ cal = GNOME_Evolution_Calendar_CalFactory_getCal (f->data, priv->uri, priv->type,
+ BONOBO_OBJREF (priv->listener), &ev);
+ if (BONOBO_EX (&ev))
+ continue;
+
+ priv->cal = cal;
+
+ return TRUE;
+ }
+
+ return FALSE;
}
/**
* cal_client_new:
*
* Creates a new calendar client. It should be initialized by calling
- * cal_client_open_calendar().
+ * cal_client_open().
*
* Return value: A newly-created calendar client, or NULL if the client could
* not be constructed because it could not contact the calendar server.
**/
CalClient *
-cal_client_new (void)
+cal_client_new (const char *uri, CalObjType type)
{
CalClient *client;
client = g_object_new (CAL_CLIENT_TYPE, NULL);
- if (!cal_client_construct (client)) {
- g_message ("cal_client_new(): could not construct the calendar client");
- g_object_unref (G_OBJECT (client));
+ if (!fetch_corba_cal (client, uri, type)) {
+ g_object_unref (client);
+
return NULL;
}
-
+
return client;
}
@@ -800,74 +1311,8 @@ cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer da
client->priv->auth_user_data = data;
}
-static gboolean
-real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists, gboolean *supported)
-{
- CalClientPrivate *priv;
- GNOME_Evolution_Calendar_Listener corba_listener;
- int unsupported;
- GList *f;
- CORBA_Environment ev;
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
- g_assert (priv->uri == NULL);
-
- g_return_val_if_fail (str_uri != NULL, FALSE);
-
- priv->listener = cal_listener_new (cal_opened_cb,
- cal_set_mode_cb,
- obj_updated_cb,
- obj_removed_cb,
- backend_error_cb,
- categories_changed_cb,
- client);
- if (!priv->listener) {
- g_message ("cal_client_open_calendar(): could not create the listener");
- return FALSE;
- }
-
- corba_listener = (GNOME_Evolution_Calendar_Listener) (BONOBO_OBJREF (priv->listener));
-
- priv->load_state = CAL_CLIENT_LOAD_LOADING;
- priv->uri = g_strdup (str_uri);
-
- unsupported = 0;
- for (f = priv->factories; f; f = f->next) {
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Calendar_CalFactory_open (f->data, str_uri,
- only_if_exists,
- corba_listener, &ev);
- if (!BONOBO_EX (&ev)) {
- if (supported != NULL)
- *supported = TRUE;
- return TRUE;
- }
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod))
- unsupported++;
- CORBA_exception_free (&ev);
- }
-
- if (supported != NULL) {
- if (unsupported == g_list_length (priv->factories))
- *supported = FALSE;
- else
- *supported = TRUE;
- }
-
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
-
- return FALSE;
-}
-
/**
- * cal_client_open_calendar:
+ * cal_client_open
* @client: A calendar client.
* @str_uri: URI of calendar to open.
* @only_if_exists: FALSE if the calendar should be opened even if there
@@ -882,93 +1327,167 @@ real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exi
* Return value: TRUE on success, FALSE on failure to issue the open request.
**/
gboolean
-cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists)
+cal_client_open (CalClient *client, gboolean only_if_exists, GError **error)
{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- return real_open_calendar (client, str_uri, only_if_exists, NULL);
-}
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
-static char *
-get_fall_back_uri (gboolean tasks)
-{
- if (tasks)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Tasks/tasks.ics");
- else
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Calendar/calendar.ics");
-}
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
-static char *
-get_default_uri (gboolean tasks)
-{
- EConfigListener *db;
- char *uri;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ priv->load_state = CAL_CLIENT_LOAD_LOADING;
+
+ GNOME_Evolution_Calendar_Cal_open (priv->cal, only_if_exists, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- db = e_config_listener_new ();
+ status = our_op->status;
- if (tasks)
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/tasks_uri");
- else
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/calendar_uri");
- g_object_unref (G_OBJECT (db));
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- if (!uri || *uri == '\0')
- uri = get_fall_back_uri (tasks);
+ if (status == E_CALENDAR_STATUS_OK)
+ priv->load_state = CAL_CLIENT_LOAD_LOADED;
else
- uri = cal_util_expand_uri (uri, tasks);
-
- return uri;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0, status);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-gboolean
-cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists)
+typedef struct {
+ CalClient *client;
+
+ gboolean exists;
+} CalClientAsyncData;
+
+static gboolean
+open_async (gpointer data)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad = data;
+ GError *error = NULL;
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ cal_client_open (ccad->client, ccad->exists, &error);
- default_uri = get_default_uri (FALSE);
- fall_back = get_fall_back_uri (FALSE);
-
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ g_clear_error (&error);
- g_free (default_uri);
- g_free (fall_back);
+ g_object_unref (ccad);
+ g_free (ccad);
- return result;
+ return FALSE;
}
-gboolean
-cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists)
+void
+cal_client_open_async (CalClient *client, gboolean only_if_exists)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (client));
+
+ ccad = g_new0 (CalClientAsyncData, 1);
+ ccad->client = g_object_ref (client);
+ ccad->exists = only_if_exists;
+ /* FIXME This should really spawn a new thread */
+ g_idle_add (open_async, ccad);
+}
+
+gboolean
+cal_client_remove_calendar (CalClient *client, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- default_uri = get_default_uri (TRUE);
- fall_back = get_fall_back_uri (TRUE);
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ e_mutex_lock (our_op->mutex);
- g_free (default_uri);
- g_free (fall_back);
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
- return result;
+ GNOME_Evolution_Calendar_Cal_remove (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+#if 0
/* Builds an URI list out of a CORBA string sequence */
static GList *
build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
@@ -981,6 +1500,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
return uris;
}
+#endif
/**
* cal_client_uri_list:
@@ -993,6 +1513,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
GList *
cal_client_uri_list (CalClient *client, CalMode mode)
{
+#if 0
CalClientPrivate *priv;
GNOME_Evolution_Calendar_StringSeq *uri_seq;
GList *uris = NULL;
@@ -1026,8 +1547,12 @@ cal_client_uri_list (CalClient *client, CalMode mode)
}
return uris;
+#endif
+
+ return NULL;
}
+
/**
* cal_client_get_load_state:
* @client: A calendar client.
@@ -1076,33 +1601,72 @@ cal_client_get_uri (CalClient *client)
* @client: A calendar client.
*
* Queries whether the calendar client can perform modifications
- * on the calendar or not.
+ * on the calendar or not. Whether the backend is read only or not
+ * is specified, on exit, in the @read_only argument.
*
- * Return value: TRUE if the calendar is read-only, FALSE otherwise.
+ * Return value: TRUE if the call was successful, FALSE if there was an error.
*/
gboolean
-cal_client_is_read_only (CalClient *client)
+cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CORBA_boolean read_only;
-
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
- if (priv->load_state != CAL_CLIENT_LOAD_LOADED)
- return FALSE;
CORBA_exception_init (&ev);
- read_only = GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
+
+ GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("cal_client_is_read_only: could not call isReadOnly method");
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
CORBA_exception_free (&ev);
- return read_only;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *read_only = our_op->bool;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ return status;
}
/**
@@ -1115,119 +1679,269 @@ cal_client_is_read_only (CalClient *client)
* is loaded or being loaded, or %NULL if the client has not started a
* load request yet or the calendar has no associated email address.
**/
-const char *
-cal_client_get_cal_address (CalClient *client)
+gboolean
+cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error)
{
CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+
+ e_mutex_lock (client->priv->mutex);
- if (priv->cal_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *cal_address;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- cal_address = GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->cal_address = g_strdup (cal_address);
- CORBA_free (cal_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->cal_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *cal_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_alarm_email_address (CalClient *client)
+gboolean
+cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->alarm_email_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *email_address;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- email_address = GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->alarm_email_address = g_strdup (email_address);
- CORBA_free (email_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->alarm_email_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *alarm_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_ldap_attribute (CalClient *client)
+gboolean
+cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->ldap_attribute == NULL) {
- CORBA_Environment ev;
- CORBA_char *ldap_attribute;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- ldap_attribute = GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->ldap_attribute = g_strdup (ldap_attribute);
- CORBA_free (ldap_attribute);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->ldap_attribute;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *ldap_attribute = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-static void
-load_static_capabilities (CalClient *client)
+static gboolean
+load_static_capabilities (CalClient *client, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
char *cap;
priv = client->priv;
if (priv->capabilities)
- return;
-
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
CORBA_exception_init (&ev);
- cap = GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
- if (!BONOBO_EX (&ev))
- priv->capabilities = g_strdup (cap);
- else
- priv->capabilities = g_strdup ("");
- CORBA_free (cap);
+ GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ cap = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
static gboolean
check_capability (CalClient *client, const char *cap)
{
CalClientPrivate *priv;
-
+
priv = client->priv;
- load_static_capabilities (client);
- if (strstr (priv->capabilities, cap))
+ /* FIXME Check result */
+ load_static_capabilities (client, NULL);
+ if (priv->capabilities && strstr (priv->capabilities, cap))
return TRUE;
return FALSE;
@@ -1269,15 +1983,6 @@ cal_client_get_save_schedules (CalClient *client)
return check_capability (client, CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
}
-/* Converts our representation of a calendar component type into its CORBA representation */
-static GNOME_Evolution_Calendar_CalObjType
-corba_obj_type (CalObjType type)
-{
- return (((type & CALOBJ_TYPE_EVENT) ? GNOME_Evolution_Calendar_TYPE_EVENT : 0)
- | ((type & CALOBJ_TYPE_TODO) ? GNOME_Evolution_Calendar_TYPE_TODO : 0)
- | ((type & CALOBJ_TYPE_JOURNAL) ? GNOME_Evolution_Calendar_TYPE_JOURNAL : 0));
-}
-
gboolean
cal_client_set_mode (CalClient *client, CalMode mode)
{
@@ -1302,45 +2007,6 @@ cal_client_set_mode (CalClient *client, CalMode mode)
return retval;
}
-/**
- * cal_client_get_n_objects:
- * @client: A calendar client.
- * @type: Type of objects that will be counted.
- *
- * Counts the number of calendar components of the specified @type. This can be
- * used to count how many events, to-dos, or journals there are, for example.
- *
- * Return value: Number of components.
- **/
-int
-cal_client_get_n_objects (CalClient *client, CalObjType type)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- int n;
- int t;
-
- g_return_val_if_fail (client != NULL, -1);
- g_return_val_if_fail (IS_CAL_CLIENT (client), -1);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, -1);
-
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
- n = GNOME_Evolution_Calendar_Cal_countObjects (priv->cal, t, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_n_objects(): could not get the number of objects");
- CORBA_exception_free (&ev);
- return -1;
- }
-
- CORBA_exception_free (&ev);
- return n;
-}
-
/* This is used in the callback which fetches all the timezones needed for an
object. */
@@ -1348,68 +2014,93 @@ typedef struct _CalClientGetTimezonesData CalClientGetTimezonesData;
struct _CalClientGetTimezonesData {
CalClient *client;
- /* This starts out at CAL_CLIENT_GET_SUCCESS. If an error occurs this
+ /* This starts out at E_CALENDAR_STATUS_OK. If an error occurs this
contains the last error. */
- CalClientGetStatus status;
+ ECalendarStatus status;
};
-CalClientGetStatus
-cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent **icalcomp)
+gboolean
+cal_client_get_default_object (CalClient *client, icalcomponent **icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, type, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_default_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GTK+ main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -1423,64 +2114,89 @@ cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent
*
* Return value: Result code based on the status of the operation.
**/
-CalClientGetStatus
-cal_client_get_object (CalClient *client, const char *uid, icalcomponent **icalcomp)
+gboolean
+cal_client_get_object (CalClient *client, const char *uid, const char *rid, icalcomponent **icalcomp, GError **error)
{
+
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, rid ? rid : "", &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GLib main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -1491,106 +2207,18 @@ cal_client_get_object_timezones_cb (icalparameter *param,
CalClientGetTimezonesData *cb_data = data;
const char *tzid;
icaltimezone *zone;
- CalClientGetStatus status;
+ GError *error = NULL;
tzid = icalparameter_get_tzid (param);
if (!tzid) {
- cb_data->status = CAL_CLIENT_GET_SYNTAX_ERROR;
+ cb_data->status = E_CALENDAR_STATUS_INVALID_OBJECT;
return;
}
- status = cal_client_get_timezone (cb_data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
- cb_data->status = status;
-}
-
-
-CalClientGetStatus
-cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- icalcomponent *icalcomp;
- icaltimezone *tmp_zone;
-
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_GET_NOT_FOUND);
-
- g_return_val_if_fail (zone != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
- if (!tzid || !tzid[0]) {
- *zone = NULL;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* If it is UTC, we return the special UTC timezone. */
- if (!strcmp (tzid, "UTC")) {
- *zone = icaltimezone_get_utc_timezone ();
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* See if we already have it in the cache. */
- tmp_zone = g_hash_table_lookup (priv->timezones, tzid);
- if (tmp_zone) {
- *zone = tmp_zone;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *zone = NULL;
-
- /* We don't already have it, so we try to get it from the server. */
- CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getTimezoneObject (priv->cal, (char *) tzid, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_timezone(): could not get the object");
- goto out;
- }
-
- icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
-
- if (!icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- tmp_zone = icaltimezone_new ();
- if (!tmp_zone) {
- /* FIXME: Needs better error code - out of memory. Or just
- abort like GLib does? */
- retval = CAL_CLIENT_GET_NOT_FOUND;
- goto out;
- }
-
- if (!icaltimezone_set_component (tmp_zone, icalcomp)) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- /* Now add it to the cache, to avoid the server call in future. */
- g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (tmp_zone),
- tmp_zone);
-
- *zone = tmp_zone;
- retval = CAL_CLIENT_GET_SUCCESS;
-
- out:
-
- CORBA_exception_free (&ev);
- return retval;
+ if (!cal_client_get_timezone (cb_data->client, tzid, &zone, &error))
+ cb_data->status = error->code;
+
+ g_clear_error (&error);
}
/* Resolves TZIDs for the recurrence generator. */
@@ -1599,7 +2227,6 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
{
CalClient *client;
icaltimezone *zone = NULL;
- CalClientGetStatus status;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (data), NULL);
@@ -1607,219 +2234,180 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
client = CAL_CLIENT (data);
/* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
+ cal_client_get_timezone (client, tzid, &zone, NULL);
return zone;
}
-
-/* Builds an UID list out of a CORBA UID sequence */
-static GList *
-build_uid_list (GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
-{
- GList *uids;
- int i;
-
- uids = NULL;
-
- for (i = 0; i < seq->_length; i++)
- uids = g_list_prepend (uids, g_strdup (seq->_buffer[i]));
-
- return uids;
-}
-
-/**
- * cal_client_get_uids:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- *
- * Queries a calendar for a list of unique identifiers corresponding to calendar
- * objects whose type matches one of the types specified in the @type flags.
- *
- * Return value: A list of strings that are the sought UIDs. This should be
- * freed using the cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_uids (CalClient *client, CalObjType type)
+gboolean
+cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- int t;
- GList *uids;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (change_id != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getUIDs (priv->cal, t, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_uids(): could not get the list of UIDs");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return uids;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* Builds a GList of CalClientChange structures from the CORBA sequence */
-static GList *
-build_change_list (GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
-{
- GList *list = NULL;
- icalcomponent *icalcomp;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjChange *corba_coc;
- CalClientChange *ccc;
+ GNOME_Evolution_Calendar_Cal_getChanges (client->priv->cal, type, change_id, &ev);
- corba_coc = &seq->_buffer[i];
- ccc = g_new (CalClientChange, 1);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- icalcomp = icalparser_parse_string (corba_coc->calobj);
- if (!icalcomp)
- continue;
+ CORBA_exception_free (&ev);
- ccc->comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- g_object_unref (G_OBJECT (ccc->comp));
- continue;
- }
- ccc->type = corba_coc->type;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, ccc);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- list = g_list_reverse (list);
+ status = our_op->status;
+ *changes = our_op->list;
- return list;
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-GList *
-cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id)
+
+/**
+ * cal_client_get_object_list:
+ * @client:
+ * @query:
+ *
+ *
+ *
+ * Return value:
+ **/
+gboolean
+cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjChangeSeq *seq;
- int t;
- GList *changes;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_changes(): could not get the list of changes");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- changes = build_change_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return changes;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* FIXME: Not used? */
-#if 0
-/* Builds a GList of CalObjInstance structures from the CORBA sequence */
-static GList *
-build_object_instance_list (GNOME_Evolution_Calendar_CalObjInstanceSeq *seq)
-{
- GList *list;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
+ GNOME_Evolution_Calendar_Cal_getObjectList (client->priv->cal, query, &ev);
- list = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjInstance *corba_icoi;
- CalObjInstance *icoi;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- corba_icoi = &seq->_buffer[i];
- icoi = g_new (CalObjInstance, 1);
+ CORBA_exception_free (&ev);
- icoi->uid = g_strdup (corba_icoi->uid);
- icoi->start = corba_icoi->start;
- icoi->end = corba_icoi->end;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, icoi);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- list = g_list_reverse (list);
- return list;
-}
-#endif
-
-/**
- * cal_client_get_objects_in_range:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- * @start: Start time for query.
- * @end: End time for query.
- *
- * Queries a calendar for the objects that occur or recur in the specified range
- * of time.
- *
- * Return value: A list of UID strings. This should be freed using the
- * cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- GList *uids;
- int t;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ status = our_op->status;
+ *objects = our_op->list;
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
-
- t = corba_obj_type (type);
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
- seq = GNOME_Evolution_Calendar_Cal_getObjectsInRange (priv->cal, t, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_objects_in_range(): could not get the objects");
- CORBA_exception_free (&ev);
- return NULL;
+gboolean
+cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error)
+{
+ GList *ical_objects = NULL;
+ GList *l;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+
+ if (!cal_client_get_object_list (client, query, &ical_objects, error))
+ return FALSE;
+
+ *objects = NULL;
+ for (l = ical_objects; l; l = l->next) {
+ CalComponent *comp;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, l->data);
+ *objects = g_list_prepend (*objects, comp);
}
- CORBA_exception_free (&ev);
+
+ g_list_free (ical_objects);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ return TRUE;
+}
+
+void
+cal_client_free_object_list (GList *objects)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ icalcomponent_free (l->data);
- return uids;
+ g_list_free (objects);
}
/**
@@ -1833,57 +2421,81 @@ cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t star
*
* Returns: a GList of VFREEBUSY CalComponents
*/
-GList *
-cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end)
+gboolean
+cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_UserList *corba_list;
- GNOME_Evolution_Calendar_CalObjSeq *calobj_list;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
+ GNOME_Evolution_Calendar_UserList corba_users;
GList *l;
- GList *comp_list = NULL;
- int len, i;
+ int i, len;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ e_mutex_lock (client->priv->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
/* create the CORBA user list to be passed to the backend */
len = g_list_length (users);
- corba_list = GNOME_Evolution_Calendar_UserList__alloc ();
- CORBA_sequence_set_release (corba_list, TRUE);
- corba_list->_length = len;
- corba_list->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
+ corba_users._length = len;
+ corba_users._buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
- for (l = g_list_first (users), i = 0; l; l = l->next, i++)
- corba_list->_buffer[i] = CORBA_string_dup ((CORBA_char *) l->data);
+ for (l = users, i = 0; l; l = l->next, i++)
+ corba_users._buffer[i] = CORBA_string_dup (l->data);
- /* call the method on the backend */
CORBA_exception_init (&ev);
- calobj_list = GNOME_Evolution_Calendar_Cal_getFreeBusy (priv->cal, corba_list,
- start, end, &ev);
- CORBA_free (corba_list);
- if (BONOBO_EX (&ev) || !calobj_list) {
- if (!BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- g_message ("cal_client_get_free_busy(): could not get the objects");
+ GNOME_Evolution_Calendar_Cal_getFreeBusy (client->priv->cal, &corba_users, start, end, &ev);
+
+ CORBA_free (corba_users._buffer);
+
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
CORBA_exception_free (&ev);
- return NULL;
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- for (i = 0; i < calobj_list->_length; i++) {
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ *freebusy = NULL;
+ for (l = our_op->list; l; l = l->next) {
CalComponent *comp;
+
icalcomponent *icalcomp;
icalcomponent_kind kind;
- icalcomp = icalparser_parse_string (calobj_list->_buffer[i]);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -1896,184 +2508,17 @@ cal_client_get_free_busy (CalClient *client, GList *users,
continue;
}
- comp_list = g_list_append (comp_list, comp);
+ *freebusy = g_list_append (*freebusy, comp);
}
else
icalcomponent_free (icalcomp);
}
- CORBA_exception_free (&ev);
- CORBA_free (calobj_list);
-
- return comp_list;
-}
-
-/* Callback used when an object is updated and we must update the copy we have */
-static void
-generate_instances_obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- const char *comp_uid;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- /* OK, so we don't care about new objects that may indeed be in
- * the requested time range. We only care about the ones that
- * were returned by the first query to
- * cal_client_get_objects_in_range().
- */
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* No longer in the server, too bad */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- }
-}
-
-/* Callback used when an object is removed and we must delete the copy we have */
-static void
-generate_instances_obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-}
-
-/* Adds a component to the list; called from g_hash_table_foreach() */
-static void
-add_component (gpointer key, gpointer value, gpointer data)
-{
- CalComponent *comp;
- GList **list;
-
- comp = CAL_COMPONENT (value);
- list = data;
-
- *list = g_list_prepend (*list, comp);
-}
-
-/* Gets a list of components that recur within the specified range of time. It
- * ensures that the resulting list of CalComponent objects contains only objects
- * that are actually in the server at the time the initial
- * cal_client_get_objects_in_range() query ends.
- */
-static GList *
-get_objects_atomically (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- GList *uids;
- GHashTable *uid_comp_hash;
- GList *objects;
- guint obj_updated_id;
- guint obj_removed_id;
- GList *l;
-
- uids = cal_client_get_objects_in_range (client, type, start, end);
-
- uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* While we are getting the actual object data, keep track of changes */
-
- obj_updated_id = g_signal_connect (G_OBJECT (client), "obj_updated",
- G_CALLBACK (generate_instances_obj_updated_cb),
- uid_comp_hash);
-
- obj_removed_id = g_signal_connect (G_OBJECT (client), "obj_removed",
- G_CALLBACK (generate_instances_obj_removed_cb),
- uid_comp_hash);
-
- /* Get the objects */
-
- for (l = uids; l; l = l->next) {
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- char *uid;
- const char *comp_uid;
-
- uid = l->data;
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data
- * instead of the duped UID from the list of UIDS.
- */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* Object disappeared from the server, so don't log it */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("get_objects_atomically(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- cal_obj_uid_list_free (uids);
-
- /* Now our state is consistent with the server, so disconnect from the
- * notification signals and generate the final list of components.
- */
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- g_signal_handler_disconnect (client, obj_updated_id);
- g_signal_handler_disconnect (client, obj_removed_id);
-
- objects = NULL;
- g_hash_table_foreach (uid_comp_hash, add_component, &objects);
- g_hash_table_destroy (uid_comp_hash);
-
- return objects;
+ E_CALENDAR_CHECK_STATUS (status, error);
}
struct comp_instance {
@@ -2127,10 +2572,8 @@ compare_comp_instance (gconstpointer a, gconstpointer b)
* @cb: Callback for each generated instance.
* @cb_data: Closure data for the callback.
*
- * Does a combination of cal_client_get_objects_in_range() and
- * cal_recur_generate_instances(). It fetches the list of objects in an atomic
- * way so that the generated instances are actually in the server at the time
- * the initial cal_client_get_objects_in_range() query ends.
+ * Does a combination of cal_client_get_object_list () and
+ * cal_recur_generate_instances().
*
* The callback function should do a g_object_ref() of the calendar component
* it gets passed if it intends to keep it around.
@@ -2144,7 +2587,8 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
GList *objects;
GList *instances;
GList *l;
-
+ char *query;
+
g_return_if_fail (client != NULL);
g_return_if_fail (IS_CAL_CLIENT (client));
@@ -2156,8 +2600,13 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_return_if_fail (cb != NULL);
/* Generate objects */
+ query = g_strdup_printf ("(occur-in-time-range? (%lu) (%lu))", start, end);
+ if (!cal_client_get_object_list (client, query, &objects, NULL)) {
+ g_free (query);
+ return;
+ }
+ g_free (query);
- objects = get_objects_atomically (client, type, start, end);
instances = NULL;
for (l = objects; l; l = l->next) {
@@ -2201,64 +2650,22 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_list_free (instances);
}
-/* Builds a list of CalAlarmInstance structures */
-static GSList *
-build_alarm_instance_list (CalComponent *comp, GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
-{
- GSList *alarms;
- int i;
-
- alarms = NULL;
-
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance;
- CalComponentAlarm *alarm;
- const char *auid;
- CalAlarmInstance *instance;
-
- corba_instance = seq->_buffer + i;
-
- /* Since we want the in-commponent auid, we look for the alarm
- * in the component and fetch its "real" auid.
- */
-
- alarm = cal_component_get_alarm (comp, corba_instance->auid);
- if (!alarm)
- continue;
-
- auid = cal_component_alarm_get_uid (alarm);
- cal_component_alarm_free (alarm);
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = corba_instance->trigger;
- instance->occur_start = corba_instance->occur_start;
- instance->occur_end = corba_instance->occur_end;
-
- alarms = g_slist_prepend (alarms, instance);
- }
-
- return g_slist_reverse (alarms);
-}
-
/* Builds a list of CalComponentAlarms structures */
static GSList *
-build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq)
+build_component_alarms_list (CalClient *client, GList *object_list, time_t start, time_t end)
{
GSList *comp_alarms;
- int i;
+ GList *l;
comp_alarms = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
+ for (l = object_list; l != NULL; l = l->next) {
CalComponent *comp;
CalComponentAlarms *alarms;
icalcomponent *icalcomp;
+ CalAlarmAction omit[] = {-1};
- corba_alarms = seq->_buffer + i;
-
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -2269,11 +2676,10 @@ build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq
continue;
}
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- alarms->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
-
- comp_alarms = g_slist_prepend (comp_alarms, alarms);
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, client->priv->default_zone);
+ if (alarms)
+ comp_alarms = g_slist_prepend (comp_alarms, alarms);
}
return comp_alarms;
@@ -2297,9 +2703,9 @@ GSList *
cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
GSList *alarms;
+ char *sexp;
+ GList *object_list = NULL;
g_return_val_if_fail (client != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
@@ -2310,18 +2716,20 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
g_return_val_if_fail (start != -1 && end != -1, NULL);
g_return_val_if_fail (start <= end, NULL);
- CORBA_exception_init (&ev);
+ /* build the query string */
+ sexp = g_strdup ("(and (has-alarms? #t))");
- seq = GNOME_Evolution_Calendar_Cal_getAlarmsInRange (priv->cal, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_in_range(): could not get the alarm range");
- CORBA_exception_free (&ev);
+ /* execute the query on the server */
+ if (!cal_client_get_object_list (client, sexp, &object_list, NULL)) {
+ g_free (sexp);
return NULL;
}
- CORBA_exception_free (&ev);
- alarms = build_component_alarms_list (seq);
- CORBA_free (seq);
+ alarms = build_component_alarms_list (client, object_list, start, end);
+
+ g_list_foreach (object_list, (GFunc) g_free, NULL);
+ g_list_free (object_list);
+ g_free (sexp);
return alarms;
}
@@ -2371,11 +2779,9 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
CalComponentAlarms **alarms)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
- gboolean retval;
icalcomponent *icalcomp;
CalComponent *comp;
+ CalAlarmAction omit[] = {-1};
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
@@ -2389,40 +2795,23 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
g_return_val_if_fail (alarms != NULL, FALSE);
*alarms = NULL;
- retval = FALSE;
-
- CORBA_exception_init (&ev);
-
- corba_alarms = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid,
- start, end, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_for_object(): could not get the alarm range");
- goto out;
- }
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ if (!cal_client_get_object (client, uid, NULL, &icalcomp, NULL))
+ return FALSE;
if (!icalcomp)
- goto out;
+ return FALSE;
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
icalcomponent_free (icalcomp);
g_object_unref (G_OBJECT (comp));
- goto out;
+ return FALSE;
}
- retval = TRUE;
-
- *alarms = g_new (CalComponentAlarms, 1);
- (*alarms)->comp = comp;
- (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
- CORBA_free (corba_alarms);
+ *alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, priv->default_zone);
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return TRUE;
}
/**
@@ -2439,33 +2828,68 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
* Return value: a #CalClientResult value indicating the result of the
* operation.
*/
-CalClientResult
-cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid)
+gboolean
+cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error)
{
CalClientPrivate *priv;
- CalClientResult retval;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *uid;
-
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (auid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
cal_component_get_uid (comp, &uid);
CORBA_exception_init (&ev);
+
GNOME_Evolution_Calendar_Cal_discardAlarm (priv->cal, uid, auid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_EX (&ev))
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
@@ -2500,10 +2924,7 @@ foreach_tzid_callback (icalparameter *param, void *cbdata)
return;
if (data->include_all_timezones) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS) {
+ if (!cal_client_get_timezone (data->client, tzid, &zone, NULL)) {
data->success = FALSE;
return;
}
@@ -2642,163 +3063,192 @@ cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp)
return cal_client_get_component_as_string_internal (client, icalcomp, TRUE);
}
-CalClientResult
-cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod)
+gboolean
+cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (comp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- cal_component_commit_sequence (comp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- obj_string = cal_client_get_component_as_string_internal (client,
- cal_component_get_icalcomponent (comp),
- FALSE);
- if (obj_string == NULL)
- return CAL_CLIENT_RESULT_INVALID_OBJECT;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, mod, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_object(): could not update the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_createObject (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
-}
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
-/**
- * cal_client_update_object:
- * @client: A calendar client.
- * @comp: A calendar component object.
- *
- * Asks a calendar to update a component. Any existing component with the
- * specified component's UID will be replaced. The client program should not
- * assume that the object is actually in the server's storage until it has
- * received the "obj_updated" notification signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_object (CalClient *client, CalComponent *comp)
-{
+ status = our_op->status;
+ if (uid)
+ *uid = our_op->uid;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- return cal_client_update_object_with_mod (client, comp, CALOBJ_MOD_ALL);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-/**
- * cal_client_update_objects:
- * @client: A calendar client.
- * @icalcomp: A toplevel VCALENDAR libical component.
- *
- * Asks a calendar to add or update one or more components, possibly including
- * VTIMEZONE data. Any existing components with the same UIDs will be
- * replaced. The VTIMEZONE data will be compared to existing VTIMEZONEs in
- * the calendar, and the VTIMEZONEs may possibly be renamed, as well as all
- * references to them throughout the VCALENDAR.
- *
- * The client program should not assume that the objects are actually in the
- * server's storage until it has received the "obj_updated" notification
- * signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_objects (CalClient *client, icalcomponent *icalcomp)
+gboolean
+cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (icalcomp != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not update the objects");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_modifyObject (priv->cal, icalcomponent_as_ical_string (icalcomp), mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-CalClientResult
-cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod)
+gboolean
+cal_client_remove_object_with_mod (CalClient *client, const char *uid,
+ const char *rid, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, mod, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_remove_object(): could not remove the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, uid, rid ? rid : "", mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2813,69 +3263,319 @@ cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjMod
* Return value: a #CalClientResult value indicating the result of the
* operation.
**/
-CalClientResult
-cal_client_remove_object (CalClient *client, const char *uid)
+gboolean
+cal_client_remove_object (CalClient *client, const char *uid, GError **error)
{
- return cal_client_remove_object_with_mod (client, uid, CALOBJ_MOD_ALL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ return cal_client_remove_object_with_mod (client, uid, NULL, CALOBJ_MOD_ALL, error);
}
-CalClientResult
-cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg)
+gboolean
+cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- GNOME_Evolution_Calendar_UserList *user_list;
- char *obj_string;
- int i;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_receiveObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- obj_string = GNOME_Evolution_Calendar_Cal_sendObject (priv->cal, obj_string, &user_list, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) {
- retval = CAL_CLIENT_SEND_INVALID_OBJECT;
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_Busy)) {
- retval = CAL_CLIENT_SEND_BUSY;
- if (error_msg)
- *error_msg = g_strdup (((GNOME_Evolution_Calendar_Cal_Busy *)(CORBA_exception_value (&ev)))->errorMsg);
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied)) {
- retval = CAL_CLIENT_SEND_PERMISSION_DENIED;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not send the objects");
- retval = CAL_CLIENT_SEND_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_sendObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ icalcomponent *icalcomp;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (tzid != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* Check for well known zones and in the cache */
+ *zone = NULL;
+
+ /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
+ if (!tzid || !tzid[0]) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+ }
+
+ /* If it is UTC, we return the special UTC timezone. */
+ if (!strcmp (tzid, "UTC")) {
+ *zone = icaltimezone_get_utc_timezone ();
} else {
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- *new_icalcomp = icalparser_parse_string (obj_string);
- CORBA_free (obj_string);
-
- if (*new_icalcomp == NULL) {
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- } else {
- *users = NULL;
- for (i = 0; i < user_list->_length; i++)
- *users = g_list_append (*users, g_strdup (user_list->_buffer[i]));
- CORBA_free (user_list);
- }
+ /* See if we already have it in the cache. */
+ *zone = g_hash_table_lookup (priv->timezones, tzid);
+ }
+
+ if (*zone) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
- return retval;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
+
+ /* FIXME Invalid object status? */
+ if (!icalcomp)
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+
+ *zone = icaltimezone_new ();
+ if (!icaltimezone_set_component (*zone, icalcomp)) {
+ icaltimezone_free (*zone, 1);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+ }
+
+ /* Now add it to the cache, to avoid the server call in future. */
+ g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (*zone), *zone);
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+/**
+ * cal_client_add_timezone
+ * @client: A calendar client.
+ * @izone: The timezone to add.
+ * @error: Placeholder for error information.
+ *
+ * Add a VTIMEZONE object to the given calendar.
+ *
+ * Returns: TRUE if successful, FALSE otherwise.
+ */
+gboolean
+cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ const char *tzobj;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (izone != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* convert icaltimezone into a string */
+ tzobj = icalcomponent_as_ical_string (icaltimezone_get_component (izone));
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_addTimezone (priv->cal, tzobj, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2888,20 +3588,68 @@ cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
* Return value: A query object that will emit notification signals as calendar
* components are added and removed from the query in the server.
**/
-CalQuery *
-cal_client_get_query (CalClient *client, const char *sexp)
+gboolean
+cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error)
{
- CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, FALSE);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (sexp != NULL, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ our_op->listener = query_listener_new ();
+ GNOME_Evolution_Calendar_Cal_getQuery (client->priv->cal, sexp, BONOBO_OBJREF (our_op->listener), &ev);
- return cal_query_new (client, priv->cal, sexp);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *query = our_op->query;
+
+ bonobo_object_unref (BONOBO_OBJECT (our_op->listener));
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -2910,19 +3658,16 @@ cal_client_get_query (CalClient *client, const char *sexp)
DATE-TIME values into specific times. (Most of our IDL interface uses
time_t values to pass specific times from the server to the client.) */
static gboolean
-cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
+cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- char *tzid, *obj_string;
+ char *tzid;
icaltimezone *tmp_zone;
- GString *vcal_string;
- gboolean retval = FALSE;
- icalcomponent *vtimezone_comp;
- char *vtimezone_as_string;
- CORBA_Environment ev;
priv = client->priv;
+ /* FIXME This is highly broken since there is no locking */
+
/* If the zone is NULL or UTC we don't need to do anything. */
if (!zone)
return TRUE;
@@ -2940,89 +3685,128 @@ cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
/* Now we have to send it to the server, in case it doesn't already
have it. */
-
- vcal_string = g_string_new (NULL);
- g_string_append (vcal_string,
- "BEGIN:VCALENDAR\n"
- "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
- "VERSION:2.0\n");
-
- /* Convert the timezone to a string and add it. */
- vtimezone_comp = icaltimezone_get_component (zone);
- if (!vtimezone_comp) {
- g_string_free (vcal_string, TRUE);
- return FALSE;
- }
-
- /* We don't need to free this string as libical owns it. */
- vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp);
- g_string_append (vcal_string, vtimezone_as_string);
-
- g_string_append (vcal_string, "END:VCALENDAR\n");
-
- obj_string = vcal_string->str;
- g_string_free (vcal_string, FALSE);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_ensure_timezone_on_server(): could not add the timezone to the server");
- goto out;
- }
-
- retval = TRUE;
-
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return cal_client_add_timezone (client, zone, error);
}
-
gboolean
-cal_client_set_default_timezone (CalClient *client, icaltimezone *zone)
+cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- gboolean retval = FALSE;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *tzid;
-
- g_return_val_if_fail (client != NULL, FALSE);
+
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
g_return_val_if_fail (zone != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- FALSE);
-
/* Make sure the server has the VTIMEZONE data. */
- if (!cal_client_ensure_timezone_on_server (client, zone))
+ if (!cal_client_ensure_timezone_on_server (client, zone, error))
return FALSE;
- /* Now set the default timezone on the server. */
- CORBA_exception_init (&ev);
- tzid = icaltimezone_get_tzid (zone);
- GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal,
- (char *) tzid, &ev);
+ e_mutex_lock (priv->mutex);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_set_default_timezone(): could not set the default timezone");
- goto out;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
}
- retval = TRUE;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
- priv->default_zone = zone;
+ /* FIXME Adding it to the server to change the tzid */
+ tzid = icaltimezone_get_tzid (zone);
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
- out:
+ GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+/**
+ * cal_client_get_error_message
+ * @status: A status code.
+ *
+ * Get an error message for the given status code.
+ *
+ * Returns: the error message.
+ */
+const char *
+cal_client_get_error_message (ECalendarStatus status)
+{
+ switch (status) {
+ case E_CALENDAR_STATUS_INVALID_ARG :
+ return _("Invalid argument");
+ case E_CALENDAR_STATUS_BUSY :
+ return _("Backend is busy");
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE :
+ return _("Repository is offline");
+ case E_CALENDAR_STATUS_NO_SUCH_CALENDAR :
+ return _("No such calendar");
+ case E_CALENDAR_STATUS_OBJECT_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_INVALID_OBJECT :
+ return _("Invalid object");
+ case E_CALENDAR_STATUS_URI_NOT_LOADED :
+ return _("URI not loaded");
+ case E_CALENDAR_STATUS_URI_ALREADY_LOADED :
+ return _("URI already loaded");
+ case E_CALENDAR_STATUS_PERMISSION_DENIED :
+ return _("Permission denied");
+ case E_CALENDAR_STATUS_CARD_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS :
+ return _("Object ID already exists");
+ case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED :
+ return _("Protocol not supported");
+ case E_CALENDAR_STATUS_CANCELLED :
+ return _("Operation has been cancelled");
+ case E_CALENDAR_STATUS_COULD_NOT_CANCEL :
+ return _("Could not cancel operation");
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED :
+ return _("Authentication failed");
+ case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED :
+ return _("Authentication required");
+ case E_CALENDAR_STATUS_CORBA_EXCEPTION :
+ return _("A CORBA esception has occurred");
+ case E_CALENDAR_STATUS_OTHER_ERROR :
+ return _("Unknown error");
+ }
+
+ return NULL;
+}
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
index 961ba5d993..277522f097 100644
--- a/calendar/cal-client/cal-client.h
+++ b/calendar/cal-client/cal-client.h
@@ -25,6 +25,7 @@
#include <cal-util/cal-recur.h>
#include <cal-util/cal-util.h>
#include <cal-client/cal-query.h>
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -37,6 +38,7 @@ G_BEGIN_DECLS
#define IS_CAL_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_TYPE))
#define CAL_CLIENT_OPEN_STATUS_ENUM_TYPE (cal_client_open_status_enum_get_type ())
+#define CAL_CLIENT_REMOVE_STATUS_ENUM_TYPE (cal_client_remove_status_enum_get_type ())
#define CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE (cal_client_set_mode_status_enum_get_type ())
#define CAL_MODE_ENUM_TYPE (cal_mode_enum_get_type ())
@@ -76,14 +78,6 @@ typedef enum {
CAL_CLIENT_RESULT_PERMISSION_DENIED
} CalClientResult;
-typedef enum {
- CAL_CLIENT_SEND_SUCCESS,
- CAL_CLIENT_SEND_CORBA_ERROR,
- CAL_CLIENT_SEND_INVALID_OBJECT,
- CAL_CLIENT_SEND_BUSY,
- CAL_CLIENT_SEND_PERMISSION_DENIED
-} CalClientSendResult;
-
/* Whether the client is not loaded, is being loaded, or is already loaded */
typedef enum {
CAL_CLIENT_LOAD_NOT_LOADED,
@@ -104,10 +98,7 @@ struct _CalClientClass {
/* Notification signals */
void (* cal_opened) (CalClient *client, CalClientOpenStatus status);
- void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
-
- void (* obj_updated) (CalClient *client, const char *uid);
- void (* obj_removed) (CalClient *client, const char *uid);
+ void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
void (* backend_error) (CalClient *client, const char *message);
@@ -129,21 +120,13 @@ GType cal_client_open_status_enum_get_type (void);
GType cal_client_set_mode_status_enum_get_type (void);
GType cal_mode_enum_get_type (void);
-CalClient *cal_client_construct (CalClient *client);
-
-CalClient *cal_client_new (void);
+CalClient *cal_client_new (const char *uri, CalObjType type);
void cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data);
-/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
- values. This will typically be from the user's timezone setting. Call this
- before using any other functions. It will pass the default timezone on to
- the server. Returns TRUE on success. */
-gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone);
-
-gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists);
-gboolean cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists);
-gboolean cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_open (CalClient *client, gboolean only_if_exists, GError **error);
+void cal_client_open_async (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_remove_calendar (CalClient *client, GError **error);
GList *cal_client_uri_list (CalClient *client, CalMode mode);
@@ -151,11 +134,10 @@ CalClientLoadState cal_client_get_load_state (CalClient *client);
const char *cal_client_get_uri (CalClient *client);
-gboolean cal_client_is_read_only (CalClient *client);
-
-const char *cal_client_get_cal_address (CalClient *client);
-const char *cal_client_get_alarm_email_address (CalClient *client);
-const char *cal_client_get_ldap_attribute (CalClient *client);
+gboolean cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error);
+gboolean cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error);
+gboolean cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error);
+gboolean cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error);
gboolean cal_client_get_one_alarm_only (CalClient *client);
gboolean cal_client_get_organizer_must_attend (CalClient *client);
@@ -164,28 +146,23 @@ gboolean cal_client_get_static_capability (CalClient *client, const char *cap);
gboolean cal_client_set_mode (CalClient *client, CalMode mode);
-int cal_client_get_n_objects (CalClient *client, CalObjType type);
-
-CalClientGetStatus cal_client_get_default_object (CalClient *client,
- CalObjType type,
- icalcomponent **icalcomp);
+gboolean cal_client_get_default_object (CalClient *client,
+ icalcomponent **icalcomp, GError **error);
-CalClientGetStatus cal_client_get_object (CalClient *client,
- const char *uid,
- icalcomponent **icalcomp);
+gboolean cal_client_get_object (CalClient *client,
+ const char *uid,
+ const char *rid,
+ icalcomponent **icalcomp,
+ GError **error);
-CalClientGetStatus cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone);
+gboolean cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error);
-GList *cal_client_get_uids (CalClient *client, CalObjType type);
-GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id);
+gboolean cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error);
+gboolean cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error);
+void cal_client_free_object_list (GList *objects);
-GList *cal_client_get_objects_in_range (CalClient *client, CalObjType type,
- time_t start, time_t end);
-
-GList *cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end);
+gboolean cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error);
void cal_client_generate_instances (CalClient *client, CalObjType type,
time_t start, time_t end,
@@ -199,24 +176,25 @@ gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid,
time_t start, time_t end,
CalComponentAlarms **alarms);
-CalClientResult cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid);
-
-/* Add or update a single object. When adding an object only builtin timezones
- are allowed. To use external VTIMEZONE data call update_objects() instead.*/
-CalClientResult cal_client_update_object (CalClient *client, CalComponent *comp);
-CalClientResult cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod);
+gboolean cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error);
+gboolean cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error);
+gboolean cal_client_remove_object (CalClient *client, const char *uid, GError **error);
+gboolean cal_client_remove_object_with_mod (CalClient *client, const char *uid, const char *rid, CalObjModType mod, GError **error);
-/* Add or update multiple objects, possibly including VTIMEZONE data. */
-CalClientResult cal_client_update_objects (CalClient *client, icalcomponent *icalcomp);
+gboolean cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error);
-CalClientResult cal_client_remove_object (CalClient *client, const char *uid);
-CalClientResult cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod);
+gboolean cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
+gboolean cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
-CalClientSendResult cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg);
+gboolean cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error);
+gboolean cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error);
+/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
+ values. This will typically be from the user's timezone setting. Call this
+ before using any other functions. It will pass the default timezone on to
+ the server. Returns TRUE on success. */
+gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error);
-CalQuery *cal_client_get_query (CalClient *client, const char *sexp);
+gboolean cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error);
/* Resolves TZIDs for the recurrence generator. */
icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
@@ -225,6 +203,7 @@ icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
used by the component. It also includes a 'METHOD:PUBLISH' property. */
char* cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp);
+const char * cal_client_get_error_message (ECalendarStatus status);
diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c
index c7beef8c97..ac04be7c07 100644
--- a/calendar/cal-client/cal-listener.c
+++ b/calendar/cal-client/cal-listener.c
@@ -19,6 +19,9 @@
*/
#include <config.h>
+
+#include <bonobo/bonobo-main.h>
+#include "cal-marshal.h"
#include "cal-listener.h"
@@ -26,10 +29,7 @@
/* Private part of the CalListener structure */
struct CalListenerPrivate {
/* Notification functions and their closure data */
- CalListenerCalOpenedFn cal_opened_fn;
CalListenerCalSetModeFn cal_set_mode_fn;
- CalListenerObjUpdatedFn obj_updated_fn;
- CalListenerObjRemovedFn obj_removed_fn;
CalListenerErrorOccurredFn error_occurred_fn;
CalListenerCategoriesChangedFn categories_changed_fn;
gpointer fn_data;
@@ -38,124 +38,178 @@ struct CalListenerPrivate {
gboolean notify : 1;
};
-
+/* Signal IDs */
+enum {
+ READ_ONLY,
+ CAL_ADDRESS,
+ ALARM_ADDRESS,
+ LDAP_ATTRIBUTE,
+ STATIC_CAPABILITIES,
+ OPEN,
+ REMOVE,
+ CREATE_OBJECT,
+ MODIFY_OBJECT,
+ REMOVE_OBJECT,
+ DISCARD_ALARM,
+ RECEIVE_OBJECTS,
+ SEND_OBJECTS,
+ DEFAULT_OBJECT,
+ OBJECT,
+ OBJECT_LIST,
+ GET_TIMEZONE,
+ ADD_TIMEZONE,
+ SET_DEFAULT_TIMEZONE,
+ GET_CHANGES,
+ GET_FREE_BUSY,
+ QUERY,
+ LAST_SIGNAL
+};
-static void cal_listener_class_init (CalListenerClass *klass);
-static void cal_listener_init (CalListener *listener, CalListenerClass *klass);
-static void cal_listener_finalize (GObject *object);
-
-static void impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- CORBA_Environment *ev);
-static void impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev);
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyErrorOccurred (PortableServer_Servant servant,
- const CORBA_char *message,
- CORBA_Environment *ev);
-static void impl_notifyCategoriesChanged (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_StringSeq *categories,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (CalListener,
- GNOME_Evolution_Calendar_Listener,
- BONOBO_TYPE_OBJECT,
- cal_listener);
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
+{
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_InvalidObject:
+ return E_CALENDAR_STATUS_INVALID_OBJECT;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
-/* Class initialization function for the calendar listener */
static void
-cal_listener_class_init (CalListenerClass *klass)
+impl_notifyReadOnly (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_boolean read_only,
+ CORBA_Environment *ev)
{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) klass;
+ CalListener *listener;
+ CalListenerPrivate *priv;
- parent_class = g_type_class_peek_parent (klass);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- klass->epv.notifyCalOpened = impl_notifyCalOpened;
- klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
- klass->epv.notifyObjUpdated = impl_notifyObjUpdated;
- klass->epv.notifyObjRemoved = impl_notifyObjRemoved;
- klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
- klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+ if (!priv->notify)
+ return;
- object_class->finalize = cal_listener_finalize;
+ g_signal_emit (G_OBJECT (listener), signals[READ_ONLY], 0, convert_status (status), read_only);
}
-/* Object initialization function for the calendar listener */
static void
-cal_listener_init (CalListener *listener, CalListenerClass *klass)
+impl_notifyCalAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
+ CalListener *listener;
CalListenerPrivate *priv;
- priv = g_new0 (CalListenerPrivate, 1);
- listener->priv = priv;
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = TRUE;
+ g_signal_emit (G_OBJECT (listener), signals[CAL_ADDRESS], 0, convert_status (status), address);
}
-/* Finalize handler for the calendar listener */
static void
-cal_listener_finalize (GObject *object)
+impl_notifyAlarmEmailAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_LISTENER (object));
-
- listener = CAL_LISTENER (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
- priv->fn_data = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = FALSE;
+ g_signal_emit (G_OBJECT (listener), signals[ALARM_ADDRESS], 0, convert_status (status), address);
+}
- g_free (priv);
- listener->priv = NULL;
+static void
+impl_notifyLDAPAttribute (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *ldap_attribute,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[LDAP_ATTRIBUTE], 0, convert_status (status), ldap_attribute);
}
-
+static void
+impl_notifyStaticCapabilities (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *capabilities,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
-/* CORBA servant implementation */
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[STATIC_CAPABILITIES], 0, convert_status (status));
+}
/* ::notifyCalOpened method */
static void
impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OPEN], 0, convert_status (status));
+}
+
+static void
+impl_notifyCalRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- CORBA_Environment aev;
- GNOME_Evolution_Calendar_Cal cal_copy;
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
@@ -163,63 +217,388 @@ impl_notifyCalOpened (PortableServer_Servant servant,
if (!priv->notify)
return;
- CORBA_exception_init (&aev);
- cal_copy = CORBA_Object_duplicate (cal, &aev);
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectCreated (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *uid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[CREATE_OBJECT], 0, convert_status (status), uid);
+}
+
+static void
+impl_notifyObjectModified (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- if (aev._major != CORBA_NO_EXCEPTION) {
- g_message ("Listener_notifyCalOpened(): could not duplicate the calendar");
- CORBA_exception_free (&aev);
+ if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[MODIFY_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyAlarmDiscarded (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DISCARD_ALARM], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsReceived (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[RECEIVE_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsSent (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SEND_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyDefaultObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DEFAULT_OBJECT], 0, convert_status (status), object);
+}
+
+static void
+impl_notifyObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT], 0, convert_status (status), object);
+}
+
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
}
- CORBA_exception_free (&aev);
- g_assert (priv->cal_opened_fn != NULL);
- (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data);
+ return list;
+}
+
+static void
+impl_notifyObjectListRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *object_list, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT_LIST], 0, convert_status (status), object_list);
+
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* ::notifyCalSetMode method */
static void
-impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev)
+impl_notifyTimezoneRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_TIMEZONE], 0, convert_status (status), object);
+}
+static void
+impl_notifyTimezoneAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *tzid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[ADD_TIMEZONE], 0, convert_status (status), tzid);
+}
- g_assert (priv->cal_set_mode_fn != NULL);
- (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
+static void
+impl_notifyDefaultTimezoneSet (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SET_DEFAULT_TIMEZONE], 0, convert_status (status));
+}
+
+static GList *
+build_change_list (const GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
+{
+ GList *list = NULL;
+ icalcomponent *icalcomp;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ GNOME_Evolution_Calendar_CalObjChange *corba_coc;
+ CalClientChange *ccc;
+
+ corba_coc = &seq->_buffer[i];
+ ccc = g_new (CalClientChange, 1);
+
+ icalcomp = icalparser_parse_string (corba_coc->calobj);
+ if (!icalcomp)
+ continue;
+
+ ccc->comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (ccc->comp));
+ continue;
+ }
+ ccc->type = corba_coc->type;
+
+ list = g_list_prepend (list, ccc);
+ }
+
+ list = g_list_reverse (list);
+
+ return list;
}
-/* ::notifyObjUpdated method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyChanges (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjChangeSeq *seq,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+ GList *changes, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+ if (!priv->notify)
+ return;
+
+ changes = build_change_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_CHANGES], 0, convert_status (status), changes);
+
+ for (l = changes; l; l = l->next)
+ g_free (l->data);
+ g_list_free (changes);
+}
+
+static GList *
+build_free_busy_list (const GNOME_Evolution_Calendar_CalObjSeq *seq)
+{
+ GList *list = NULL;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+
+ icalcomp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!icalcomp)
+ continue;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VFREEBUSY_COMPONENT) {
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (comp));
+ continue;
+ }
+
+ list = g_list_append (list, comp);
+ } else {
+ icalcomponent_free (icalcomp);
+ }
+ }
+
+ return list;
+}
+
+static void
+impl_notifyFreeBusy (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjSeq *seq,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *freebusy, *l;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ freebusy = build_free_busy_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_FREE_BUSY], 0, convert_status (status), freebusy);
+
+ for (l = freebusy; l; l = l->next)
+ g_free (l->data);
+ g_list_free (freebusy);
+}
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (listener, uid, priv->fn_data);
+static void
+impl_notifyQuery (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_Query query,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[QUERY], 0, convert_status (status), query);
}
-/* ::notifyObjRemoved method */
+/* ::notifyCalSetMode method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
+impl_notifyCalSetMode (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_Listener_SetModeStatus status,
+ GNOME_Evolution_Calendar_CalMode mode,
CORBA_Environment *ev)
{
CalListener *listener;
@@ -231,10 +610,13 @@ impl_notifyObjRemoved (PortableServer_Servant servant,
if (!priv->notify)
return;
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (listener, uid, priv->fn_data);
+ g_message ("notify_set_mode");
+
+ g_assert (priv->cal_set_mode_fn != NULL);
+ (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
}
+
/* ::notifyErrorOccurred method */
static void
impl_notifyErrorOccurred (PortableServer_Servant servant,
@@ -250,6 +632,8 @@ impl_notifyErrorOccurred (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_error");
+
g_assert (priv->error_occurred_fn != NULL);
(* priv->error_occurred_fn) (listener, message, priv->fn_data);
}
@@ -269,21 +653,283 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_categories");
+
g_assert (priv->categories_changed_fn != NULL);
(* priv->categories_changed_fn) (listener, categories, priv->fn_data);
}
+/* Object initialization function for the calendar listener */
+static void
+cal_listener_init (CalListener *listener, CalListenerClass *klass)
+{
+ CalListenerPrivate *priv;
+
+ priv = g_new0 (CalListenerPrivate, 1);
+ listener->priv = priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+
+ priv->notify = TRUE;
+}
+
+/* Finalize handler for the calendar listener */
+static void
+cal_listener_finalize (GObject *object)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_LISTENER (object));
+
+ listener = CAL_LISTENER (object);
+ priv = listener->priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+ priv->fn_data = NULL;
+
+ priv->notify = FALSE;
+
+ g_free (priv);
+ listener->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar listener */
+static void
+cal_listener_class_init (CalListenerClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ klass->epv.notifyReadOnly = impl_notifyReadOnly;
+ klass->epv.notifyCalAddress = impl_notifyCalAddress;
+ klass->epv.notifyAlarmEmailAddress = impl_notifyAlarmEmailAddress;
+ klass->epv.notifyLDAPAttribute = impl_notifyLDAPAttribute;
+ klass->epv.notifyStaticCapabilities = impl_notifyStaticCapabilities;
+ klass->epv.notifyCalOpened = impl_notifyCalOpened;
+ klass->epv.notifyCalRemoved = impl_notifyCalRemoved;
+ klass->epv.notifyObjectCreated = impl_notifyObjectCreated;
+ klass->epv.notifyObjectModified = impl_notifyObjectModified;
+ klass->epv.notifyObjectRemoved = impl_notifyObjectRemoved;
+ klass->epv.notifyAlarmDiscarded = impl_notifyAlarmDiscarded;
+ klass->epv.notifyObjectsReceived = impl_notifyObjectsReceived;
+ klass->epv.notifyObjectsSent = impl_notifyObjectsSent;
+ klass->epv.notifyDefaultObjectRequested = impl_notifyDefaultObjectRequested;
+ klass->epv.notifyObjectRequested = impl_notifyObjectRequested;
+ klass->epv.notifyObjectListRequested = impl_notifyObjectListRequested;
+ klass->epv.notifyTimezoneRequested = impl_notifyTimezoneRequested;
+ klass->epv.notifyTimezoneAdded = impl_notifyTimezoneAdded;
+ klass->epv.notifyDefaultTimezoneSet = impl_notifyDefaultTimezoneSet;
+ klass->epv.notifyChanges = impl_notifyChanges;
+ klass->epv.notifyFreeBusy = impl_notifyFreeBusy;
+ klass->epv.notifyQuery = impl_notifyQuery;
+ klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
+ klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
+ klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+
+ object_class->finalize = cal_listener_finalize;
+
+ signals[READ_ONLY] =
+ g_signal_new ("read_only",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, read_only),
+ NULL, NULL,
+ cal_marshal_VOID__INT_BOOLEAN,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN);
+ signals[CAL_ADDRESS] =
+ g_signal_new ("cal_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, cal_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ALARM_ADDRESS] =
+ g_signal_new ("alarm_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, alarm_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[LDAP_ATTRIBUTE] =
+ g_signal_new ("ldap_attribute",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, ldap_attribute),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[STATIC_CAPABILITIES] =
+ g_signal_new ("static_capabilities",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, static_capabilities),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OPEN] =
+ g_signal_new ("open",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, open),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE] =
+ g_signal_new ("remove",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[CREATE_OBJECT] =
+ g_signal_new ("create_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, create_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[MODIFY_OBJECT] =
+ g_signal_new ("modify_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, modify_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE_OBJECT] =
+ g_signal_new ("remove_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DISCARD_ALARM] =
+ g_signal_new ("discard_alarm",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, discard_alarm),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[RECEIVE_OBJECTS] =
+ g_signal_new ("receive_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, receive_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[SEND_OBJECTS] =
+ g_signal_new ("send_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, send_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DEFAULT_OBJECT] =
+ g_signal_new ("default_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, default_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT] =
+ g_signal_new ("object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT_LIST] =
+ g_signal_new ("object_list",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object_list),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_TIMEZONE] =
+ g_signal_new ("get_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ADD_TIMEZONE] =
+ g_signal_new ("add_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, add_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[SET_DEFAULT_TIMEZONE] =
+ g_signal_new ("set_default_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, set_default_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[GET_CHANGES] =
+ g_signal_new ("get_changes",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_changes),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_FREE_BUSY] =
+ g_signal_new ("get_free_busy",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_free_busy),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[QUERY] =
+ g_signal_new ("query",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, query),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+}
+
+BONOBO_TYPE_FUNC_FULL (CalListener,
+ GNOME_Evolution_Calendar_Listener,
+ BONOBO_TYPE_OBJECT,
+ cal_listener);
+
/**
* cal_listener_construct:
* @listener: A calendar listener.
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
+ * @cal_removed_fn: Function that will be called to notify that a calendar was
+ * removed
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -297,10 +943,7 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
**/
CalListener *
cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
@@ -309,19 +952,13 @@ cal_listener_construct (CalListener *listener,
g_return_val_if_fail (listener != NULL, NULL);
g_return_val_if_fail (IS_CAL_LISTENER (listener), NULL);
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
g_return_val_if_fail (cal_set_mode_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
priv = listener->priv;
- priv->cal_opened_fn = cal_opened_fn;
priv->cal_set_mode_fn = cal_set_mode_fn;
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
priv->error_occurred_fn = error_occurred_fn;
priv->categories_changed_fn = categories_changed_fn;
priv->fn_data = fn_data;
@@ -333,10 +970,6 @@ cal_listener_construct (CalListener *listener,
* cal_listener_new:
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -348,28 +981,22 @@ cal_listener_construct (CalListener *listener,
* Return value: A newly-created #CalListener object.
**/
CalListener *
-cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
{
CalListener *listener;
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
- listener = g_object_new (CAL_LISTENER_TYPE, NULL);
+ listener = g_object_new (CAL_LISTENER_TYPE,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
+
return cal_listener_construct (listener,
- cal_opened_fn,
cal_set_mode_fn,
- obj_updated_fn,
- obj_removed_fn,
error_occurred_fn,
categories_changed_fn,
fn_data);
diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h
index d0f9a718a4..1230104999 100644
--- a/calendar/cal-client/cal-listener.h
+++ b/calendar/cal-client/cal-listener.h
@@ -23,6 +23,7 @@
#include <bonobo/bonobo-object.h>
#include "evolution-calendar.h"
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -48,26 +49,46 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_Listener__epv epv;
+
+ /* Signals */
+ void (*read_only) (CalListener *listener, ECalendarStatus status, gboolean read_only);
+ void (*cal_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*alarm_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*ldap_attribute) (CalListener *listener, ECalendarStatus status, const char *ldap_attribute);
+ void (*static_capabilities) (CalListener *listener, ECalendarStatus status, const char *capabilities);
+
+ void (*open) (CalListener *listener, ECalendarStatus status);
+ void (*remove) (CalListener *listener, ECalendarStatus status);
+
+ void (*create_object) (CalListener *listener, ECalendarStatus status, const char *id);
+ void (*modify_object) (CalListener *listener, ECalendarStatus status);
+ void (*remove_object) (CalListener *listener, ECalendarStatus status);
+
+ void (*discard_alarm) (CalListener *listener, ECalendarStatus status);
+
+ void (*receive_objects) (CalListener *listener, ECalendarStatus status);
+ void (*send_objects) (CalListener *listener, ECalendarStatus status);
+
+ void (*default_object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object_list) (CalListener *listener, ECalendarStatus status, GList **objects);
+
+ void (*get_timezone) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*add_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+ void (*set_default_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+
+ void (*get_changes) (CalListener *listener, ECalendarStatus status, GList *changes);
+ void (*get_free_busy) (CalListener *listener, ECalendarStatus status, GList *freebusy);
+
+ void (*query) (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query);
} CalListenerClass;
/* Notification functions */
-typedef void (* CalListenerCalOpenedFn) (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data);
-
typedef void (* CalListenerCalSetModeFn) (CalListener *listener,
GNOME_Evolution_Calendar_Listener_SetModeStatus status,
GNOME_Evolution_Calendar_CalMode mode,
gpointer data);
-typedef void (* CalListenerObjUpdatedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-typedef void (* CalListenerObjRemovedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-
typedef void (* CalListenerErrorOccurredFn) (CalListener *listener,
const char *message,
gpointer data);
@@ -80,18 +101,12 @@ typedef void (* CalListenerCategoriesChangedFn) (CalListener *listener,
GType cal_listener_get_type (void);
CalListener *cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
-CalListener *cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+CalListener *cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
diff --git a/calendar/cal-client/cal-marshal.list b/calendar/cal-client/cal-marshal.list
new file mode 100644
index 0000000000..e0ca019669
--- /dev/null
+++ b/calendar/cal-client/cal-marshal.list
@@ -0,0 +1,6 @@
+NONE:INT
+NONE:POINTER
+NONE:INT,STRING
+NONE:INT,BOOL
+NONE:INT,POINTER
+NONE:STRING,INT
diff --git a/calendar/cal-client/cal-query.c b/calendar/cal-client/cal-query.c
index 914af5db28..e77f5ad3e9 100644
--- a/calendar/cal-client/cal-query.c
+++ b/calendar/cal-client/cal-query.c
@@ -24,7 +24,8 @@
#include <string.h>
#include <bonobo/bonobo-exception.h>
-#include "cal-util/cal-util-marshal.h"
+#include "cal-marshal.h"
+#include "cal-client.h"
#include "cal-query.h"
#include "query-listener.h"
@@ -32,143 +33,88 @@
/* Private part of the CalQuery structure */
struct _CalQueryPrivate {
- /* Our query listener implementation */
- QueryListener *ql;
-
/* Handle to the query in the server */
- GNOME_Evolution_Calendar_Query corba_query;
+ GNOME_Evolution_Calendar_Query query;
+
+ /* Our query listener implementation */
+ QueryListener *listener;
/* The CalClient associated with this query */
CalClient *client;
};
-
-
-static void cal_query_class_init (CalQueryClass *klass);
-static void cal_query_init (CalQuery *query, CalQueryClass *klass);
-static void cal_query_finalize (GObject *object);
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_QUERY,
+ PROP_LISTENER,
+ PROP_CLIENT
+};
/* Signal IDs */
enum {
- OBJ_UPDATED,
- OBJ_REMOVED,
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
QUERY_DONE,
- EVAL_ERROR,
LAST_SIGNAL
};
-static guint query_signals[LAST_SIGNAL];
+static guint signals[LAST_SIGNAL];
static GObjectClass *parent_class;
-/**
- * cal_query_get_type:
- *
- * Registers the #CalQuery class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalQuery class.
- **/
-GType
-cal_query_get_type (void)
+static void
+objects_added_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_type = 0;
+ CalQuery *query;
- if (!cal_query_type) {
- static GTypeInfo info = {
- sizeof (CalQueryClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_query_class_init,
- NULL, NULL,
- sizeof (CalQuery),
- 0,
- (GInstanceInitFunc) cal_query_init
- };
- cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
- }
+ query = CAL_QUERY (data);
- return cal_query_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_ADDED], 0, objects);
}
-GType
-cal_query_done_status_enum_get_type (void)
+static void
+objects_modified_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_done_status_enum_type = 0;
+ CalQuery *query;
- if (!cal_query_done_status_enum_type) {
- static GEnumValue values [] = {
- { CAL_QUERY_DONE_SUCCESS, "CalQueryDoneSuccess", "success" },
- { CAL_QUERY_DONE_PARSE_ERROR, "CalQueryDoneParseError", "parse-error" },
- { -1, NULL, NULL }
- };
+ query = CAL_QUERY (data);
- cal_query_done_status_enum_type =
- g_enum_register_static ("CalQueryDoneStatusEnum", values);
- }
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_MODIFIED], 0, objects);
+}
+
+static void
+objects_removed_cb (QueryListener *listener, GList *uids, gpointer data)
+{
+ CalQuery *query;
+
+ query = CAL_QUERY (data);
- return cal_query_done_status_enum_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_REMOVED], 0, uids);
}
-/* Class initialization function for the calendar query */
static void
-cal_query_class_init (CalQueryClass *klass)
+query_progress_cb (QueryListener *listener, const char *message, int percent, gpointer data)
{
- GObjectClass *object_class;
+ CalQuery *query;
- object_class = (GObjectClass *) klass;
+ query = CAL_QUERY (data);
- parent_class = g_type_class_peek_parent (klass);
+ g_signal_emit (G_OBJECT (query), signals[QUERY_PROGRESS], 0, message, percent);
+}
- query_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_updated),
- NULL, NULL,
- cal_util_marshal_VOID__STRING_BOOLEAN_INT_INT,
- G_TYPE_NONE, 4,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_INT,
- G_TYPE_INT);
- query_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- query_signals[QUERY_DONE] =
- g_signal_new ("query_done",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, query_done),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_STRING,
- G_TYPE_NONE, 2,
- CAL_QUERY_DONE_STATUS_ENUM_TYPE,
- G_TYPE_STRING);
- query_signals[EVAL_ERROR] =
- g_signal_new ("eval_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, eval_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
+static void
+query_done_cb (QueryListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalQuery *query;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->query_done = NULL;
- klass->eval_error = NULL;
+ query = CAL_QUERY (data);
- object_class->finalize = cal_query_finalize;
+ g_signal_emit (G_OBJECT (query), signals[QUERY_DONE], 0, status);
}
/* Object initialization function for the calendar query */
@@ -180,191 +126,193 @@ cal_query_init (CalQuery *query, CalQueryClass *klass)
priv = g_new0 (CalQueryPrivate, 1);
query->priv = priv;
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
+ priv->listener = NULL;
+ priv->query = CORBA_OBJECT_NIL;
}
-/* Finalize handler for the calendar query */
static void
-cal_query_finalize (GObject *object)
+cal_query_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
CalQuery *query;
CalQueryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_QUERY (object));
-
+
query = CAL_QUERY (object);
priv = query->priv;
-
- /* The server keeps a copy of the query listener, so we must unref it */
- query_listener_stop_notification (priv->ql);
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
-
- if (priv->corba_query != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (priv->corba_query, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("cal_query_destroy(): Could not release/unref the query");
-
- CORBA_exception_free (&ev);
- priv->corba_query = CORBA_OBJECT_NIL;
+
+ switch (property_id) {
+ case PROP_QUERY:
+ priv->query = bonobo_object_dup_ref (g_value_get_pointer (value), NULL);
+ break;
+ case PROP_LISTENER:
+ priv->listener = bonobo_object_ref (g_value_get_pointer (value));
+
+ g_signal_connect (G_OBJECT (priv->listener), "objects_added",
+ G_CALLBACK (objects_added_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_modified",
+ G_CALLBACK (objects_modified_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_removed",
+ G_CALLBACK (objects_removed_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_progress",
+ G_CALLBACK (query_progress_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_done",
+ G_CALLBACK (query_done_cb), query);
+ break;
+ case PROP_CLIENT:
+ priv->client = CAL_CLIENT (g_value_dup_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
-
- g_free (priv);
- query->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/* Callback used when an object is updated in the query */
static void
-obj_updated_cb (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data)
+cal_query_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
CalQuery *query;
- int n;
-
- query = CAL_QUERY (data);
+ CalQueryPrivate *priv;
+
+ query = CAL_QUERY (object);
+ priv = query->priv;
- for (n = 0; n < uids->_length; n++) {
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_UPDATED], 0,
- uids->_buffer[n], query_in_progress,
- (int) n_scanned, (int) total);
+ switch (property_id) {
+ case PROP_QUERY:
+ g_value_set_pointer (value, priv->query);
+ break;
+ case PROP_LISTENER:
+ g_value_set_pointer (value, priv->listener);
+ break;
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
-/* Callback used when an object is removed from the query */
-static void
-obj_removed_cb (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data)
-{
- CalQuery *query;
-
- query = CAL_QUERY (data);
-
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_REMOVED],
- 0, uid);
-}
-/* Callback used when the query terminates */
+/* Finalize handler for the calendar query */
static void
-query_done_cb (QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_finalize (GObject *object)
{
CalQuery *query;
- CalQueryDoneStatus status;
+ CalQueryPrivate *priv;
- query = CAL_QUERY (data);
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_QUERY (object));
- switch (corba_status) {
- case GNOME_Evolution_Calendar_QueryListener_SUCCESS:
- status = CAL_QUERY_DONE_SUCCESS;
- break;
+ query = CAL_QUERY (object);
+ priv = query->priv;
- case GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR:
- status = CAL_QUERY_DONE_PARSE_ERROR;
- break;
+ /* The server keeps a copy of the query listener, so we must unref it */
+ g_signal_handlers_disconnect_matched (priv->listener, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, query);
+ bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- default:
- g_assert_not_reached ();
- return;
- }
+ if (priv->query != CORBA_OBJECT_NIL)
+ bonobo_object_release_unref (priv->query, NULL);
- g_signal_emit (G_OBJECT (query), query_signals[QUERY_DONE], 0,
- status, error_str);
+ g_free (priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-/* Callback used when an error occurs when evaluating the query */
+/* Class initialization function for the calendar query */
static void
-eval_error_cb (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_class_init (CalQueryClass *klass)
{
- CalQuery *query;
+ GObjectClass *object_class;
+ GParamSpec *param;
+
+ object_class = (GObjectClass *) klass;
- query = CAL_QUERY (data);
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = cal_query_set_property;
+ object_class->get_property = cal_query_get_property;
+ object_class->finalize = cal_query_finalize;
- g_signal_emit (G_OBJECT (query), query_signals[EVAL_ERROR], 0,
- error_str);
+ param = g_param_spec_pointer ("query", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_QUERY, param);
+ param = g_param_spec_pointer ("listener", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_LISTENER, param);
+ param = g_param_spec_object ("client", NULL, NULL, CAL_CLIENT_TYPE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_CLIENT, param);
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
/**
- * cal_query_construct:
- * @query: A calendar query.
- * @cal: Handle to an open calendar.
- * @sexp: S-expression that defines the query.
+ * cal_query_get_type:
*
- * Constructs a query object by issuing the query creation request to the
- * calendar server.
+ * Registers the #CalQuery class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same value as @query on success, or NULL if the request
- * failed.
+ * Return value: The type ID of the #CalQuery class.
**/
-CalQuery *
-cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+GType
+cal_query_get_type (void)
{
- CalQueryPrivate *priv;
- GNOME_Evolution_Calendar_QueryListener corba_ql;
- CORBA_Environment ev;
-
- g_return_val_if_fail (query != NULL, NULL);
- g_return_val_if_fail (IS_CAL_QUERY (query), NULL);
- g_return_val_if_fail (sexp != NULL, NULL);
-
- priv = query->priv;
-
- priv->ql = query_listener_new (obj_updated_cb,
- obj_removed_cb,
- query_done_cb,
- eval_error_cb,
- query);
- if (!priv->ql) {
- g_message ("cal_query_construct(): Could not create the query listener");
- return NULL;
- }
+ static GType cal_query_type = 0;
- corba_ql = BONOBO_OBJREF (priv->ql);
-
- CORBA_exception_init (&ev);
- priv->corba_query = GNOME_Evolution_Calendar_Cal_getQuery (cal, sexp, corba_ql, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate)) {
- g_message ("cal_query_construct(): The server could not create the query");
- goto error;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_query_construct(): Could not issue the getQuery() request");
- goto error;
+ if (!cal_query_type) {
+ static GTypeInfo info = {
+ sizeof (CalQueryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_query_class_init,
+ NULL, NULL,
+ sizeof (CalQuery),
+ 0,
+ (GInstanceInitFunc) cal_query_init
+ };
+ cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
}
- CORBA_exception_free (&ev);
-
- return query;
-
- error:
-
- CORBA_exception_free (&ev);
-
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
- return NULL;
+ return cal_query_type;
}
/**
@@ -379,20 +327,12 @@ cal_query_construct (CalQuery *query,
* Return value: A newly-created query object, or NULL if the request failed.
**/
CalQuery *
-cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client)
{
CalQuery *query;
- query = g_object_new (CAL_QUERY_TYPE, NULL);
-
- if (!cal_query_construct (query, cal, sexp)) {
- g_object_unref (G_OBJECT (query));
- return NULL;
- }
-
- query->priv->client = client;
+ query = g_object_new (CAL_QUERY_TYPE, "query", corba_query, "listener",
+ listener, "client", client, NULL);
return query;
}
@@ -412,3 +352,23 @@ cal_query_get_client (CalQuery *query)
return query->priv->client;
}
+
+void
+cal_query_start (CalQuery *query)
+{
+ CalQueryPrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_if_fail (query != NULL);
+ g_return_if_fail (IS_CAL_QUERY (query));
+
+ priv = query->priv;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Query_start (priv->query, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": Unable to start query");
+
+ CORBA_exception_free (&ev);
+}
diff --git a/calendar/cal-client/cal-query.h b/calendar/cal-client/cal-query.h
index 77429035fa..05390dd12a 100644
--- a/calendar/cal-client/cal-query.h
+++ b/calendar/cal-client/cal-query.h
@@ -22,7 +22,8 @@
#define CAL_QUERY_H
#include <glib-object.h>
-
+#include "cal-client-types.h"
+#include "query-listener.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -37,14 +38,6 @@ typedef struct _CalClient CalClient;
#define IS_CAL_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_QUERY_TYPE))
#define IS_CAL_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_QUERY_TYPE))
-#define CAL_QUERY_DONE_STATUS_ENUM_TYPE (cal_query_done_status_enum_get_type ())
-
-/* Status values when a query terminates */
-typedef enum {
- CAL_QUERY_DONE_SUCCESS,
- CAL_QUERY_DONE_PARSE_ERROR
-} CalQueryDoneStatus;
-
typedef struct _CalQueryPrivate CalQueryPrivate;
typedef struct {
@@ -58,30 +51,18 @@ typedef struct {
GObjectClass parent_class;
/* Notification signals */
-
- void (* obj_updated) (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total);
- void (* obj_removed) (CalQuery *query, const char *uid);
-
- void (* query_done) (CalQuery *query, CalQueryDoneStatus status, const char *error_str);
-
- void (* eval_error) (CalQuery *query, const char *error_str);
+ void (* objects_added) (CalQuery *query, GList *objects);
+ void (* objects_modified) (CalQuery *query, GList *objects);
+ void (* objects_removed) (CalQuery *query, GList *uids);
+ void (* query_progress) (CalQuery *query, char *message, int percent);
+ void (* query_done) (CalQuery *query, ECalendarStatus status);
} CalQueryClass;
GType cal_query_get_type (void);
-GType cal_query_done_status_enum_get_type (void);
-
-CalQuery *cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
-
-CalQuery *cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
+CalQuery *cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client);
CalClient *cal_query_get_client (CalQuery *query);
-
-
+void cal_query_start (CalQuery *query);
G_END_DECLS
diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c
index cb6eed17b2..48763be50a 100644
--- a/calendar/cal-client/client-test.c
+++ b/calendar/cal-client/client-test.c
@@ -45,24 +45,37 @@ cl_printf (CalClient *client, const char *format, ...)
va_end (args);
}
-/* Dumps some interesting data from a component */
static void
-dump_component (CalComponent *comp)
+objects_added_cb (GObject *object, GList *objects, gpointer data)
{
- const char *uid;
- CalComponentText summary;
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_uid (comp, &uid);
+static void
+objects_modified_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
+}
- printf ("UID %s\n", uid);
+static void
+objects_removed_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_summary (comp, &summary);
- if (summary.value)
- printf ("\tSummary: `%s', altrep `%s'\n",
- summary.value,
- summary.altrep ? summary.altrep : "NONE");
- else
- printf ("\tNo summary\n");
+static void
+query_done_cb (GObject *object, ECalendarStatus status, gpointer data)
+{
+ cl_printf (data, "Query done\n");
}
/* Lists the UIDs of objects in a calendar, called as an idle handler */
@@ -70,47 +83,38 @@ static gboolean
list_uids (gpointer data)
{
CalClient *client;
- GList *uids;
+ GList *objects = NULL;
GList *l;
-
+
client = CAL_CLIENT (data);
- uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY);
-
- cl_printf (client, "UIDs: ");
+ g_message ("Blah");
+
+ if (!cal_client_get_object_list (client, "(contains? \"any\" \"Test4\")", &objects, NULL))
+ return FALSE;
+
+ cl_printf (client, "UIDS: ");
- if (!uids)
+ if (!objects)
printf ("none\n");
else {
- for (l = uids; l; l = l->next) {
- char *uid;
+ for (l = objects; l; l = l->next) {
+ const char *uid;
- uid = l->data;
+ uid = icalcomponent_get_uid (l->data);
printf ("`%s' ", uid);
}
printf ("\n");
- for (l = uids; l; l = l->next) {
- char *uid;
- CalComponent *comp;
- CalClientGetStatus status;
-
- uid = l->data;
- status = cal_client_get_object (client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
- printf ("------------------------------\n");
- dump_component (comp);
- printf ("------------------------------\n");
- g_object_unref (comp);
- } else {
- printf ("FAILED: %d\n", status);
- }
+ for (l = objects; l; l = l->next) {
+ printf ("------------------------------\n");
+ printf ("%s", icalcomponent_as_ical_string (l->data));
+ printf ("------------------------------\n");
}
}
- cal_obj_uid_list_free (uids);
+ cal_client_free_object_list (objects);
g_object_unref (client);
@@ -121,6 +125,8 @@ list_uids (gpointer data)
static void
cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
{
+ CalQuery *query;
+
cl_printf (client, "Load/create %s\n",
((status == CAL_CLIENT_OPEN_SUCCESS) ? "success" :
(status == CAL_CLIENT_OPEN_ERROR) ? "error" :
@@ -129,40 +135,29 @@ cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
"unknown status value"));
if (status == CAL_CLIENT_OPEN_SUCCESS) {
- GList *comp_list;
-
- /* get free/busy information */
- comp_list = cal_client_get_free_busy (client, NULL, 0, time (NULL));
- if (comp_list) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- char *comp_str;
-
- comp_str = cal_component_get_as_string (CAL_COMPONENT (l->data));
- g_object_unref (l->data);
- cl_printf (client, "Free/Busy -> %s\n", comp_str);
- g_free (comp_str);
- }
- g_list_free (comp_list);
- }
-
+ if (!cal_client_get_query (client, "(contains? \"any\" \"Test4\")", &query, NULL))
+ g_warning (G_STRLOC ": Unable to obtain query");
+
+ g_signal_connect (G_OBJECT (query), "objects_added",
+ G_CALLBACK (objects_added_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_modified",
+ G_CALLBACK (objects_modified_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_removed",
+ G_CALLBACK (objects_removed_cb), client);
+ g_signal_connect (G_OBJECT (query), "query_done",
+ G_CALLBACK (query_done_cb), client);
+
+ cal_query_start (query);
+
g_idle_add (list_uids, client);
}
else
g_object_unref (client);
}
-/* Callback used when an object is updated */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- cl_printf (client, "Object updated: %s\n", uid);
-}
-
/* Callback used when a client is destroyed */
static void
-client_destroy_cb (GObject *object, gpointer data)
+client_destroy_cb (gpointer data, GObject *object)
{
if (CAL_CLIENT (object) == client1)
client1 = NULL;
@@ -177,33 +172,24 @@ client_destroy_cb (GObject *object, gpointer data)
/* Creates a calendar client and tries to load the specified URI into it */
static void
-create_client (CalClient **client, const char *uri, gboolean only_if_exists)
+create_client (CalClient **client, const char *uri, CalObjType type, gboolean only_if_exists)
{
- gboolean result;
-
- *client = cal_client_new ();
+ *client = cal_client_new (uri, type);
if (!*client) {
- g_message ("create_client(): could not create the client");
+ g_message (G_STRLOC ": could not create the client");
exit (1);
}
- g_signal_connect (*client, "destroy",
- G_CALLBACK (client_destroy_cb),
- NULL);
+ g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
g_signal_connect (*client, "cal_opened",
G_CALLBACK (cal_opened_cb),
NULL);
- g_signal_connect (*client, "obj_updated",
- G_CALLBACK (obj_updated_cb),
- NULL);
printf ("Calendar loading `%s'...\n", uri);
- result = cal_client_open_calendar (*client, uri, only_if_exists);
-
- if (!result) {
- g_message ("create_client(): failure when issuing calendar open request `%s'",
+ if (!cal_client_open (*client, only_if_exists, NULL)) {
+ g_message (G_STRLOC ": failure when issuing calendar open request `%s'",
uri);
exit (1);
}
@@ -212,8 +198,6 @@ create_client (CalClient **client, const char *uri, gboolean only_if_exists)
int
main (int argc, char **argv)
{
- char *dir;
-
bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
@@ -225,10 +209,9 @@ main (int argc, char **argv)
exit (1);
}
- dir = g_strdup_printf ("%s/evolution/local/Calendar/calendar.ics", g_get_home_dir ());
- create_client (&client1, dir, FALSE);
- g_free (dir);
- create_client (&client2, "/cvs/evolution/calendar/cal-client/test.ics", TRUE);
+ create_client (&client1, "file:///home/gnome24-evolution-new-calendar/evolution/local/Calendar",
+ CALOBJ_TYPE_EVENT, FALSE);
+// create_client (&client2, "file:///tmp/tasks", TRUE);
bonobo_main ();
return 0;
diff --git a/calendar/cal-client/query-listener.c b/calendar/cal-client/query-listener.c
index 6bd7bfc6f7..4c8cbb4fe5 100644
--- a/calendar/cal-client/query-listener.c
+++ b/calendar/cal-client/query-listener.c
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include "cal-marshal.h"
#include "query-listener.h"
@@ -29,166 +30,164 @@
/* Private part of the QueryListener structure */
struct _QueryListenerPrivate {
- /* Callbacks for notification and their closure data */
- QueryListenerObjUpdatedFn obj_updated_fn;
- QueryListenerObjRemovedFn obj_removed_fn;
- QueryListenerQueryDoneFn query_done_fn;
- QueryListenerEvalErrorFn eval_error_fn;
- gpointer fn_data;
-
- /* Whether notification is desired */
- gboolean notify : 1;
+ int dummy;
};
-
-
-static void query_listener_class_init (QueryListenerClass *class);
-static void query_listener_init (QueryListener *ql, QueryListenerClass *class);
-static void query_listener_finalize (GObject *object);
-
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev);
-
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-
-static void impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+/* Signal IDs */
+enum {
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
+ QUERY_DONE,
+ LAST_SIGNAL
+};
-static void impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (QueryListener,
- GNOME_Evolution_Calendar_QueryListener,
- BONOBO_TYPE_OBJECT,
- query_listener);
-
-/* Class initialization function for the live search query listener */
-static void
-query_listener_class_init (QueryListenerClass *class)
+/* CORBA method implementations */
+/* FIXME This is duplicated from cal-listener.c */
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
{
- GObjectClass *object_class;
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
- object_class = (GObjectClass *) class;
+/* FIXME This is duplicated from cal-listener.c */
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
+ }
+
+ return list;
+}
- parent_class = g_type_class_peek_parent (class);
+static GList *
+build_uid_list (const GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
+{
+ GList *list;
+ int i;
- object_class->finalize = query_listener_finalize;
+ list = NULL;
+ for (i = 0; i < seq->_length; i++)
+ list = g_list_prepend (list, g_strdup (seq->_buffer[i]));
- class->epv.notifyObjUpdated = impl_notifyObjUpdated;
- class->epv.notifyObjRemoved = impl_notifyObjRemoved;
- class->epv.notifyQueryDone = impl_notifyQueryDone;
- class->epv.notifyEvalError = impl_notifyEvalError;
+ return list;
}
-/* Object initialization function for the live search query listener */
static void
-query_listener_init (QueryListener *ql, QueryListenerClass *class)
+impl_notifyObjectsAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
+ QueryListener *ql;
QueryListenerPrivate *priv;
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ priv = ql->priv;
- priv = g_new0 (QueryListenerPrivate, 1);
- ql->priv = priv;
-
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_ADDED], 0, object_list);
- priv->notify = TRUE;
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* Finalize handler for the live search query listener */
static void
-query_listener_finalize (GObject *object)
+impl_notifyObjectsModified (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (object));
-
- ql = QUERY_LISTENER (object);
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
-
- priv->notify = FALSE;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_MODIFIED], 0, object_list);
- g_free (priv);
- ql->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-
-
-/* CORBA method implementations */
-
-/* ::notifyObjUpdated() method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev)
+impl_notifyObjectsRemoved (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
+ GList *uid_list, *l;
+
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- if (!priv->notify)
- return;
+ uid_list = build_uid_list (uids);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_REMOVED], 0, uid_list);
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (ql, uids, query_in_progress, n_scanned, total, priv->fn_data);
+ for (l = uid_list; l; l = l->next)
+ g_free (l->data);
+ g_list_free (uid_list);
}
-/* ::notifyObjRemoved() method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyQueryProgress (PortableServer_Servant servant,
+ const CORBA_char *message,
+ const CORBA_short percent,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (ql, uid, priv->fn_data);
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_PROGRESS], 0, message, percent);
}
-/* ::notifyQueryDone() method */
static void
impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
+ const GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
QueryListener *ql;
@@ -196,126 +195,110 @@ impl_notifyQueryDone (PortableServer_Servant servant,
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_DONE], 0, convert_status (status));
+}
- if (!priv->notify)
- return;
+/* Object initialization function for the live search query listener */
+static void
+query_listener_init (QueryListener *ql, QueryListenerClass *class)
+{
+ QueryListenerPrivate *priv;
- g_assert (priv->query_done_fn != NULL);
- (* priv->query_done_fn) (ql, corba_status, error_str, priv->fn_data);
+ priv = g_new0 (QueryListenerPrivate, 1);
+ ql->priv = priv;
}
-/* ::notifyEvalError() method */
+/* Finalize handler for the live search query listener */
static void
-impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev)
+query_listener_finalize (GObject *object)
{
QueryListener *ql;
QueryListenerPrivate *priv;
- ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_QUERY_LISTENER (object));
+
+ ql = QUERY_LISTENER (object);
priv = ql->priv;
- if (!priv->notify)
- return;
+ g_free (priv);
- g_assert (priv->eval_error_fn != NULL);
- (* priv->eval_error_fn) (ql, error_str, priv->fn_data);
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/**
- * query_listener_construct:
- * @ql: A query listener.
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Constructs a query listener by setting the callbacks it will use for
- * notification from the calendar server.
- *
- * Return value: The same value as @ql.
- **/
-QueryListener *
-query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+/* Class initialization function for the live search query listener */
+static void
+query_listener_class_init (QueryListenerClass *klass)
{
- QueryListenerPrivate *priv;
+ GObjectClass *object_class;
- g_return_val_if_fail (ql != NULL, NULL);
- g_return_val_if_fail (IS_QUERY_LISTENER (ql), NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
- g_return_val_if_fail (query_done_fn != NULL, NULL);
- g_return_val_if_fail (eval_error_fn != NULL, NULL);
+ object_class = (GObjectClass *) klass;
- priv = ql->priv;
+ parent_class = g_type_class_peek_parent (klass);
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
- priv->query_done_fn = query_done_fn;
- priv->eval_error_fn = eval_error_fn;
- priv->fn_data = fn_data;
+ object_class->finalize = query_listener_finalize;
- return ql;
+ klass->epv.notifyObjectsAdded = impl_notifyObjectsAdded;
+ klass->epv.notifyObjectsModified = impl_notifyObjectsModified;
+ klass->epv.notifyObjectsRemoved = impl_notifyObjectsRemoved;
+ klass->epv.notifyQueryProgress = impl_notifyQueryProgress;
+ klass->epv.notifyQueryDone = impl_notifyQueryDone;
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
-/**
- * query_listener_new:
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Creates a new query listener object.
- *
- * Return value: A newly-created query listener object.
- **/
+BONOBO_TYPE_FUNC_FULL (QueryListener,
+ GNOME_Evolution_Calendar_QueryListener,
+ BONOBO_TYPE_OBJECT,
+ query_listener);
+
QueryListener *
-query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+query_listener_new (void)
{
QueryListener *ql;
ql = g_object_new (QUERY_LISTENER_TYPE, NULL);
- return query_listener_construct (ql,
- obj_updated_fn,
- obj_removed_fn,
- query_done_fn,
- eval_error_fn,
- fn_data);
-}
-
-/**
- * query_listener_stop_notification:
- * @ql: A query listener.
- *
- * Informs a query listener that no further notification is desired. The
- * callbacks specified when the listener was created will no longer be invoked
- * after this function is called.
- **/
-void
-query_listener_stop_notification (QueryListener *ql)
-{
- QueryListenerPrivate *priv;
-
- g_return_if_fail (ql != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (ql));
-
- priv = ql->priv;
- g_return_if_fail (priv->notify != FALSE);
-
- priv->notify = FALSE;
+ return ql;
}
diff --git a/calendar/cal-client/query-listener.h b/calendar/cal-client/query-listener.h
index eeb42afc7e..6a204bbf77 100644
--- a/calendar/cal-client/query-listener.h
+++ b/calendar/cal-client/query-listener.h
@@ -22,6 +22,7 @@
#define QUERY_LISTENER_H
#include <bonobo/bonobo-object.h>
+#include "cal-client-types.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -48,47 +49,18 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_QueryListener__epv epv;
+
+ void (*objects_added) (QueryListener *listener, GList *objects);
+ void (*objects_modified) (QueryListener *listener, GList *objects);
+ void (*objects_removed) (QueryListener *listener, GList *uids);
+ void (*query_progress) (QueryListener *listener, const char *message, int percent);
+ void (*query_done) (QueryListener *listener, ECalendarStatus status);
} QueryListenerClass;
/* Notification functions */
-typedef void (* QueryListenerObjUpdatedFn) (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data);
-
-typedef void (* QueryListenerObjRemovedFn) (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data);
-
-typedef void (* QueryListenerQueryDoneFn) (
- QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus status,
- const CORBA_char *error_str,
- gpointer data);
-
-typedef void (* QueryListenerEvalErrorFn) (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data);
-
GType query_listener_get_type (void);
-
-QueryListener *query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-QueryListener *query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-void query_listener_stop_notification (QueryListener *ql);
+QueryListener *query_listener_new (void);
diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c
index 1e03c86d75..f1c32610c1 100644
--- a/calendar/cal-util/cal-util.c
+++ b/calendar/cal-util/cal-util.c
@@ -584,29 +584,7 @@ cal_util_priority_from_string (const char *string)
char *
cal_util_expand_uri (char *uri, gboolean tasks)
{
- char *file_uri, *file_name;
-
- if (!strncmp (uri, "file://", 7)) {
- file_uri = uri + 7;
- if (strlen (file_uri) > 4
- && !strcmp (file_uri + strlen (file_uri) - 4, ".ics")) {
-
- /* it's a .ics file */
- return g_strdup (uri);
- }
-
- /* we assume it's a dir and glom <type>.ics onto the end. */
- if (tasks)
- file_name = g_concat_dir_and_file (file_uri, "tasks.ics");
- else
- file_name = g_concat_dir_and_file (file_uri, "calendar.ics");
- file_uri = g_strdup_printf("file://%s", file_name);
- g_free(file_name);
- } else {
- file_uri = g_strdup (uri);
- }
-
- return file_uri;
+ return g_strdup (uri);
}
/* callback for icalcomponent_foreach_tzid */
diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c
index 1893e6b34c..05ddde2c7f 100644
--- a/calendar/conduits/calendar/calendar-conduit.c
+++ b/calendar/conduits/calendar/calendar-conduit.c
@@ -253,7 +253,7 @@ struct _ECalConduitContext {
icaltimezone *timezone;
CalComponent *default_comp;
- GList *uids;
+ GList *comps;
GList *changed;
GHashTable *changed_hash;
GList *locals;
@@ -276,7 +276,7 @@ e_calendar_context_new (guint32 pilot_id)
ctxt->client = NULL;
ctxt->timezone = NULL;
ctxt->default_comp = NULL;
- ctxt->uids = NULL;
+ ctxt->comps = NULL;
ctxt->changed = NULL;
ctxt->changed_hash = NULL;
ctxt->locals = NULL;
@@ -311,8 +311,11 @@ e_calendar_context_destroy (ECalConduitContext *ctxt)
g_object_unref (ctxt->client);
if (ctxt->default_comp != NULL)
g_object_unref (ctxt->default_comp);
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
+ if (ctxt->comps != NULL) {
+ for (l = ctxt->comps; l; l = l->next)
+ g_object_unref (l->data);
+ g_list_free (ctxt->comps);
+ }
if (ctxt->changed != NULL)
cal_client_change_list_free (ctxt->changed);
@@ -404,16 +407,24 @@ start_calendar_server_cb (CalClient *cal_client,
static int
start_calendar_server (ECalConduitContext *ctxt)
{
+ char *uri;
gboolean success = FALSE;
g_return_val_if_fail (ctxt != NULL, -2);
- ctxt->client = cal_client_new ();
-
+ /* FIXME Need a mechanism for the user to select uri's */
+ /* FIXME Can we use the cal model? */
+ uri = g_strdup_printf ("file://%s/local/Calendar/", g_get_home_dir ());
+ ctxt->client = cal_client_new (uri, CALOBJ_TYPE_EVENT);
+ g_free (uri);
+
+ if (!ctxt->client)
+ return -1;
+
g_signal_connect (ctxt->client, "cal_opened",
G_CALLBACK (start_calendar_server_cb), &success);
- if (!cal_client_open_default_calendar (ctxt->client, FALSE))
+ if (!cal_client_open (ctxt->client, FALSE, NULL))
return -1;
/* run a sub event loop to turn cal-client's async load
@@ -433,8 +444,8 @@ get_timezone (CalClient *client, const char *tzid)
icaltimezone *timezone = NULL;
timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (timezone == NULL)
- cal_client_get_timezone (client, tzid, &timezone);
+ if (timezone == NULL)
+ cal_client_get_timezone (client, tzid, &timezone, NULL);
return timezone;
}
@@ -550,7 +561,7 @@ is_all_day (CalClient *client, CalComponentDateTime *dt_start, CalComponentDateT
}
static gboolean
-process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_uid, GList **multi_ccc)
+process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_comp, GList **multi_ccc)
{
CalComponentDateTime dt_start, dt_end;
icaltimezone *tz_start, *tz_end;
@@ -562,7 +573,7 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
gboolean ret = TRUE;
*multi_ccc = NULL;
- *multi_uid = NULL;
+ *multi_comp = NULL;
if (ccc->type == CAL_CLIENT_CHANGE_DELETED)
return FALSE;
@@ -617,13 +628,14 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
dt_end.value = &end_value;
cal_component_set_dtend (clone, &dt_end);
- cal_client_update_object (ctxt->client, clone);
+ /* FIXME Error handling */
+ cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (clone), NULL, NULL);
c->comp = clone;
c->type = CAL_CLIENT_CHANGE_ADDED;
*multi_ccc = g_list_prepend (*multi_ccc, c);
- *multi_uid = g_list_prepend (*multi_uid, new_uid);
+ *multi_comp = g_list_prepend (*multi_comp, g_object_ref (c->comp));
event_start = day_end;
day_end = time_day_end_with_zone (event_start, ctxt->timezone);
@@ -632,7 +644,8 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
dt_end.value = old_end_value;
cal_component_get_uid (ccc->comp, &uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
ccc->type = CAL_CLIENT_CHANGE_DELETED;
cleanup:
@@ -1007,13 +1020,11 @@ local_record_from_uid (ECalLocalRecord *local,
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
+ GError *error = NULL;
g_assert(local!=NULL);
- status = cal_client_get_object (ctxt->client, uid, &icalcomp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (ctxt->client, uid, NULL, &icalcomp, &error)) {
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
g_object_unref (comp);
@@ -1023,7 +1034,7 @@ local_record_from_uid (ECalLocalRecord *local,
local_record_from_comp (local, comp, ctxt);
g_object_unref (comp);
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
+ } else if (error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
cal_component_set_uid (comp, uid);
@@ -1031,7 +1042,9 @@ local_record_from_uid (ECalLocalRecord *local,
g_object_unref (comp);
} else {
INFO ("Object did not exist");
- }
+ }
+
+ g_clear_error (&error);
}
static CalComponent *
@@ -1283,21 +1296,6 @@ comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
}
static void
-update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp,
- ECalConduitContext *ctxt)
-{
- CalClientResult success;
-
- g_return_if_fail (conduit != NULL);
- g_return_if_fail (comp != NULL);
-
- success = cal_client_update_object (ctxt->client, comp);
-
- if (success != CAL_CLIENT_RESULT_SUCCESS)
- WARN (_("Error while communicating with calendar server"));
-}
-
-static void
check_for_slow_setting (GnomePilotConduit *c, ECalConduitContext *ctxt)
{
GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
@@ -1360,11 +1358,13 @@ pre_sync (GnomePilotConduit *conduit,
LOG (g_message ( " Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));
/* Set the default timezone on the backend. */
- if (ctxt->timezone)
- cal_client_set_default_timezone (ctxt->client, ctxt->timezone);
+ if (ctxt->timezone) {
+ if (!cal_client_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
+ return -1;
+ }
/* Get the default component */
- if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_EVENT, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (ctxt->client, &icalcomp, NULL))
return -1;
ctxt->default_comp = cal_component_new ();
@@ -1374,27 +1374,36 @@ pre_sync (GnomePilotConduit *conduit,
return -1;
}
+ ctxt->default_comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
+ g_object_unref (ctxt->default_comp);
+ icalcomponent_free (icalcomp);
+ return -1;
+ }
+
/* Load the uid <--> pilot id mapping */
filename = map_name (ctxt);
e_pilot_map_read (filename, &ctxt->map);
g_free (filename);
/* Get the local database */
- ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_EVENT);
+ if (!cal_client_get_object_list_as_comp (ctxt->client, "(#t)", &ctxt->comps, NULL))
+ return -1;
/* Find the added, modified and deleted items */
change_id = g_strdup_printf ("pilot-sync-evolution-calendar-%d", ctxt->cfg->pilot_id);
- ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id);
+ if (!cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id, &ctxt->changed, NULL))
+ return -1;
ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_free (change_id);
/* See if we need to split up any events */
for (l = ctxt->changed; l != NULL; l = l->next) {
CalClientChange *ccc = l->data;
- GList *multi_uid = NULL, *multi_ccc = NULL;
+ GList *multi_comp = NULL, *multi_ccc = NULL;
- if (process_multi_day (ctxt, ccc, &multi_uid, &multi_ccc)) {
- ctxt->uids = g_list_concat (ctxt->uids, multi_uid);
+ if (process_multi_day (ctxt, ccc, &multi_comp, &multi_ccc)) {
+ ctxt->comps = g_list_concat (ctxt->comps, multi_comp);
added = g_list_concat (added, multi_ccc);
removed = g_list_prepend (removed, ccc);
@@ -1442,7 +1451,7 @@ pre_sync (GnomePilotConduit *conduit,
}
/* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_EVENT);
+ num_records = g_list_length (ctxt->comps);
gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
@@ -1492,8 +1501,8 @@ post_sync (GnomePilotConduit *conduit,
* a race condition if anyone changes a record elsewhere during sycnc
*/
change_id = g_strdup_printf ("pilot-sync-evolution-calendar-%d", ctxt->cfg->pilot_id);
- changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id);
- cal_client_change_list_free (changed);
+ if (cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id, &changed, NULL))
+ cal_client_change_list_free (changed);
g_free (change_id);
LOG (g_message ( "---------------------------------------------------------\n" ));
@@ -1537,7 +1546,7 @@ for_each (GnomePilotConduitSyncAbs *conduit,
ECalLocalRecord **local,
ECalConduitContext *ctxt)
{
- static GList *uids, *iterator;
+ static GList *comps, *iterator;
static int count;
g_return_val_if_fail (local != NULL, -1);
@@ -1545,17 +1554,17 @@ for_each (GnomePilotConduitSyncAbs *conduit,
if (*local == NULL) {
LOG (g_message ( "beginning for_each" ));
- uids = ctxt->uids;
+ comps = ctxt->comps;
count = 0;
- if (uids != NULL) {
- LOG (g_message ( "iterating over %d records", g_list_length (uids) ));
+ if (comps != NULL) {
+ LOG (g_message ( "iterating over %d records", g_list_length (comps)));
*local = g_new0 (ECalLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
+ local_record_from_comp (*local, comps->data, ctxt);
g_list_prepend (ctxt->locals, *local);
- iterator = uids;
+ iterator = comps;
} else {
LOG (g_message ( "no events" ));
(*local) = NULL;
@@ -1681,8 +1690,10 @@ add_record (GnomePilotConduitSyncAbs *conduit,
/* Give it a new UID otherwise it will be the uid of the default comp */
uid = cal_component_gen_uid ();
cal_component_set_uid (comp, uid);
+
+ if (!cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (comp), NULL, NULL))
+ return -1;
- update_comp (conduit, comp, ctxt);
e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
g_free (uid);
@@ -1709,7 +1720,10 @@ replace_record (GnomePilotConduitSyncAbs *conduit,
new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone);
g_object_unref (local->comp);
local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
+
+ if (!cal_client_modify_object (ctxt->client, cal_component_get_icalcomponent (new_comp),
+ CALOBJ_MOD_ALL, NULL))
+ return -1;
return retval;
}
@@ -1729,7 +1743,8 @@ delete_record (GnomePilotConduitSyncAbs *conduit,
LOG (g_message ( "delete_record: deleting %s\n", uid ));
e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
return 0;
}
diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c
index 6868368129..35251f4eb6 100644
--- a/calendar/conduits/todo/todo-conduit.c
+++ b/calendar/conduits/todo/todo-conduit.c
@@ -255,7 +255,7 @@ struct _EToDoConduitContext {
icaltimezone *timezone;
CalComponent *default_comp;
- GList *uids;
+ GList *comps;
GList *changed;
GHashTable *changed_hash;
GList *locals;
@@ -275,7 +275,7 @@ e_todo_context_new (guint32 pilot_id)
ctxt->client = NULL;
ctxt->timezone = NULL;
ctxt->default_comp = NULL;
- ctxt->uids = NULL;
+ ctxt->comps = NULL;
ctxt->changed_hash = NULL;
ctxt->changed = NULL;
ctxt->locals = NULL;
@@ -311,8 +311,11 @@ e_todo_context_destroy (EToDoConduitContext *ctxt)
if (ctxt->default_comp != NULL)
g_object_unref (ctxt->default_comp);
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
+ if (ctxt->comps != NULL) {
+ for (l = ctxt->comps; l; l = l->next)
+ g_object_unref (l->data);
+ g_list_free (ctxt->comps);
+ }
if (ctxt->changed_hash != NULL) {
g_hash_table_foreach_remove (ctxt->changed_hash, e_todo_context_foreach_change, NULL);
@@ -411,16 +414,24 @@ start_calendar_server_cb (CalClient *cal_client,
static int
start_calendar_server (EToDoConduitContext *ctxt)
{
+ char *uri;
gboolean success = FALSE;
g_return_val_if_fail (ctxt != NULL, -2);
- ctxt->client = cal_client_new ();
+ /* FIXME Need a mechanism for the user to select uri's */
+ /* FIXME Can we use the cal model? */
+ uri = g_strdup_printf ("file://%s/local/Tasks/", g_get_home_dir ());
+ ctxt->client = cal_client_new (uri, CALOBJ_TYPE_TODO);
+ g_free (uri);
+
+ if (!ctxt->client)
+ return -1;
g_signal_connect (ctxt->client, "cal_opened",
G_CALLBACK (start_calendar_server_cb), &success);
- if (!cal_client_open_default_tasks (ctxt->client, FALSE))
+ if (!cal_client_open (ctxt->client, FALSE, NULL))
return -1;
/* run a sub event loop to turn cal-client's async load
@@ -441,7 +452,7 @@ get_timezone (CalClient *client, const char *tzid)
timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
if (timezone == NULL)
- cal_client_get_timezone (client, tzid, &timezone);
+ cal_client_get_timezone (client, tzid, &timezone, NULL);
return timezone;
}
@@ -676,13 +687,11 @@ local_record_from_uid (EToDoLocalRecord *local,
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
+ GError *error = NULL;
g_assert(local!=NULL);
- status = cal_client_get_object (ctxt->client, uid, &icalcomp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (ctxt->client, uid, NULL, &icalcomp, &error)) {
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
g_object_unref (comp);
@@ -692,7 +701,7 @@ local_record_from_uid (EToDoLocalRecord *local,
local_record_from_comp (local, comp, ctxt);
g_object_unref (comp);
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
+ } else if (error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
cal_component_set_uid (comp, uid);
@@ -702,7 +711,7 @@ local_record_from_uid (EToDoLocalRecord *local,
INFO ("Object did not exist");
}
-
+ g_clear_error (&error);
}
@@ -824,21 +833,6 @@ comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
}
static void
-update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp,
- EToDoConduitContext *ctxt)
-{
- CalClientResult success;
-
- g_return_if_fail (conduit != NULL);
- g_return_if_fail (comp != NULL);
-
- success = cal_client_update_object (ctxt->client, comp);
-
- if (success != CAL_CLIENT_RESULT_SUCCESS)
- WARN (_("Error while communicating with calendar server"));
-}
-
-static void
check_for_slow_setting (GnomePilotConduit *c, EToDoConduitContext *ctxt)
{
GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
@@ -902,11 +896,13 @@ pre_sync (GnomePilotConduit *conduit,
LOG (g_message ( " Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));
/* Set the default timezone on the backend. */
- if (ctxt->timezone)
- cal_client_set_default_timezone (ctxt->client, ctxt->timezone);
+ if (ctxt->timezone) {
+ if (!cal_client_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
+ return -1;
+ }
/* Get the default component */
- if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_TODO, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (ctxt->client, &icalcomp, NULL))
return -1;
ctxt->default_comp = cal_component_new ();
@@ -916,17 +912,26 @@ pre_sync (GnomePilotConduit *conduit,
return -1;
}
+ ctxt->default_comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
+ g_object_unref (ctxt->default_comp);
+ icalcomponent_free (icalcomp);
+ return -1;
+ }
+
/* Load the uid <--> pilot id map */
filename = map_name (ctxt);
e_pilot_map_read (filename, &ctxt->map);
g_free (filename);
/* Get the local database */
- ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
+ if (!cal_client_get_object_list_as_comp (ctxt->client, "(#t)", &ctxt->comps, NULL))
+ return -1;
/* Count and hash the changes */
change_id = g_strdup_printf ("pilot-sync-evolution-todo-%d", ctxt->cfg->pilot_id);
- ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id);
+ if (!cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id, &ctxt->changed, NULL))
+ return -1;
ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_free (change_id);
@@ -956,7 +961,7 @@ pre_sync (GnomePilotConduit *conduit,
}
/* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO);
+ num_records = g_list_length (ctxt->comps);
gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
@@ -1006,8 +1011,8 @@ post_sync (GnomePilotConduit *conduit,
* a race condition if anyone changes a record elsewhere during sycnc
*/
change_id = g_strdup_printf ("pilot-sync-evolution-todo-%d", ctxt->cfg->pilot_id);
- changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id);
- cal_client_change_list_free (changed);
+ if (cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id, &changed, NULL))
+ cal_client_change_list_free (changed);
g_free (change_id);
LOG (g_message ( "---------------------------------------------------------\n" ));
@@ -1051,7 +1056,7 @@ for_each (GnomePilotConduitSyncAbs *conduit,
EToDoLocalRecord **local,
EToDoConduitContext *ctxt)
{
- static GList *uids, *iterator;
+ static GList *comps, *iterator;
static int count;
g_return_val_if_fail (local != NULL, -1);
@@ -1059,17 +1064,17 @@ for_each (GnomePilotConduitSyncAbs *conduit,
if (*local == NULL) {
LOG (g_message ( "beginning for_each" ));
- uids = ctxt->uids;
+ comps = ctxt->comps;
count = 0;
- if (uids != NULL) {
- LOG (g_message ( "iterating over %d records", g_list_length (uids) ));
+ if (comps != NULL) {
+ LOG (g_message ( "iterating over %d records", g_list_length (comps)));
*local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
+ local_record_from_comp (*local, comps->data, ctxt);
g_list_prepend (ctxt->locals, *local);
- iterator = uids;
+ iterator = comps;
} else {
LOG (g_message ( "no events" ));
(*local) = NULL;
@@ -1196,7 +1201,9 @@ add_record (GnomePilotConduitSyncAbs *conduit,
uid = cal_component_gen_uid ();
cal_component_set_uid (comp, uid);
- update_comp (conduit, comp, ctxt);
+ if (!cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (comp), NULL, NULL))
+ return -1;
+
e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
g_object_unref (comp);
@@ -1221,7 +1228,10 @@ replace_record (GnomePilotConduitSyncAbs *conduit,
new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->timezone);
g_object_unref (local->comp);
local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
+
+ if (!cal_client_modify_object (ctxt->client, cal_component_get_icalcomponent (new_comp),
+ CALOBJ_MOD_ALL, NULL))
+ return -1;
return retval;
}
@@ -1241,7 +1251,8 @@ delete_record (GnomePilotConduitSyncAbs *conduit,
LOG (g_message ( "delete_record: deleting %s\n", uid ));
e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
return 0;
}
diff --git a/calendar/gui/GNOME_Evolution_Calendar.server.in.in b/calendar/gui/GNOME_Evolution_Calendar.server.in.in
index 801cada120..09f424f69a 100644
--- a/calendar/gui/GNOME_Evolution_Calendar.server.in.in
+++ b/calendar/gui/GNOME_Evolution_Calendar.server.in.in
@@ -1,6 +1,6 @@
<oaf_info>
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Factory"
+<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Factory_2"
type="shlib"
location="@COMPONENTDIR@/libevolution-calendar.so">
@@ -15,7 +15,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Control:1.0"/>
@@ -31,26 +31,20 @@
_value="Evolution Calendar scheduling message viewer"/>
</oaf_server>
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponent"
+<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Component"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/>
+ <item value="IDL:GNOME/Evolution/Component:1.0"/>
</oaf_attribute>
- <oaf_attribute name="name" type="string"
- _value="Evolution Calendar and Tasks component"/>
-
- <oaf_attribute name="evolution:shell_component_icon" type="string"
- value="evolution-calendar.png"/>
- <oaf_attribute name="evolution:shell_component_launch_order" type="number"
- value="3"/>
+ <oaf_attribute name="name" type="string" _value="Evolution's Calendar component"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/calendar-control:1.0"/>
@@ -68,7 +62,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/tasks-control:1.0"/>
@@ -86,7 +80,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:1.0"/>
@@ -99,7 +93,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControl"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/ConfigControl:1.0"/>
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 3ee9362b65..19edf95953 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -169,6 +169,8 @@ libevolution_calendar_la_SOURCES = \
itip-utils.c \
itip-utils.h \
main.c \
+ migration.c \
+ migration.h \
misc.c \
misc.h \
print.c \
@@ -189,7 +191,8 @@ libevolution_calendar_la_LIBADD = \
$(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \
$(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
$(EVOLUTION_CALENDAR_LIBS)
libevolution_calendar_la_LDFLAGS = -avoid-version -module
diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c
index 133448e7cd..006533c6bf 100644
--- a/calendar/gui/alarm-notify/alarm-notify.c
+++ b/calendar/gui/alarm-notify/alarm-notify.c
@@ -31,26 +31,6 @@
-/* A loaded client */
-typedef struct {
- /* The actual client */
- CalClient *client;
-
- /* The URI of the client in gnome-vfs's format. This *is* the key that
- * is stored in the uri_client_hash hash table below.
- */
- EUri *uri;
-
- /* Number of times clients have requested this URI to be added to the
- * alarm notification system.
- */
- int refcount;
-
- /* the ID of the retry timeout function
- */
- int timeout_id;
-} LoadedClient;
-
/* Private part of the AlarmNotify structure */
struct _AlarmNotifyPrivate {
/* Mapping from EUri's to LoadedClient structures */
@@ -105,23 +85,7 @@ alarm_notify_init (AlarmNotify *an, AlarmNotifyClass *klass)
priv = g_new0 (AlarmNotifyPrivate, 1);
an->priv = priv;
- priv->uri_client_hash = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-/* Callback used from g_hash-table_forach(), used to destroy a loade client */
-static void
-destroy_loaded_client_cb (gpointer key, gpointer value, gpointer data)
-{
- LoadedClient *lc;
- char *str_uri;
-
- str_uri = key;
- lc = value;
-
- g_free (str_uri);
- g_object_unref (G_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
+ priv->uri_client_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
/* Finalize handler for the alarm notify system */
@@ -137,13 +101,9 @@ alarm_notify_finalize (GObject *object)
an = ALARM_NOTIFY (object);
priv = an->priv;
- g_hash_table_foreach (priv->uri_client_hash, destroy_loaded_client_cb, NULL);
-
g_hash_table_destroy (priv->uri_client_hash);
- priv->uri_client_hash = NULL;
g_free (priv);
- an->priv = NULL;
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
@@ -193,21 +153,15 @@ free_uris (GPtrArray *uris)
/* Adds an URI to the list of calendars to load on startup */
static void
-add_uri_to_load (EUri *uri)
+add_uri_to_load (const char *str_uri)
{
- char *str_uri;
GPtrArray *loaded_uris;
int i;
- /* Canonicalize the URI */
- str_uri = e_uri_to_string (uri, FALSE);
- g_assert (str_uri != NULL);
-
loaded_uris = get_calendars_to_load ();
if (!loaded_uris) {
g_message ("add_uri_to_load(): Could not get the list of calendars to load; "
"will not add `%s'", str_uri);
- g_free (str_uri);
return;
}
@@ -219,12 +173,11 @@ add_uri_to_load (EUri *uri)
* calendars.
*/
if (i != -1) {
- g_free (str_uri);
free_uris (loaded_uris);
return;
}
- g_ptr_array_add (loaded_uris, str_uri);
+ g_ptr_array_add (loaded_uris, g_strdup (str_uri));
save_calendars_to_load (loaded_uris);
free_uris (loaded_uris);
@@ -232,29 +185,22 @@ add_uri_to_load (EUri *uri)
/* Removes an URI from the list of calendars to load on startup */
static void
-remove_uri_to_load (EUri *uri)
+remove_uri_to_load (const char *str_uri)
{
- char *str_uri;
GPtrArray *loaded_uris;
char *loaded_uri;
int i;
- /* Canonicalize the URI */
- str_uri = e_uri_to_string (uri, FALSE);
- g_assert (str_uri != NULL);
-
loaded_uris = get_calendars_to_load ();
if (!loaded_uris) {
g_message ("remove_uri_to_load(): Could not get the list of calendars to load; "
"will not add `%s'", str_uri);
- g_free (str_uri);
return;
}
/* Look for the URI in the list of calendars to load */
i = find_uri_index (loaded_uris, str_uri);
- g_free (str_uri);
/* If we didn't find it, there is no need to remove it */
if (i == -1) {
@@ -291,61 +237,19 @@ AlarmNotify_removeCalendar (PortableServer_Servant servant,
{
AlarmNotify *an;
AlarmNotifyPrivate *priv;
- LoadedClient *lc;
- EUri *uri;
- char *orig_str;
- gpointer lc_ptr, orig_str_ptr;
- gboolean found;
-
- lc_ptr = NULL;
- orig_str_ptr = NULL;
+ CalClient *client;
an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
priv = an->priv;
- uri = e_uri_new (str_uri);
- if (!uri) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI,
- NULL);
- return;
- }
+ client = g_hash_table_lookup (priv->uri_client_hash, str_uri);
+ if (client) {
+ alarm_queue_remove_client (client);
- remove_uri_to_load (uri);
-
- found = g_hash_table_lookup_extended (priv->uri_client_hash, str_uri,
- &orig_str_ptr,
- &lc_ptr);
- orig_str = orig_str_ptr;
- lc = lc_ptr;
-
- e_uri_free (uri);
-
- if (!lc) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound,
- NULL);
- return;
+ g_hash_table_remove (priv->uri_client_hash, str_uri);
}
- g_assert (lc->refcount > 0);
-
- lc->refcount--;
- if (lc->refcount > 0)
- return;
-
- g_hash_table_remove (priv->uri_client_hash, str_uri);
-
- g_free (orig_str);
- g_signal_handlers_disconnect_matched (lc->client,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, lc);
- if (lc->timeout_id != -1)
- g_source_remove (lc->timeout_id);
- alarm_queue_remove_client (lc->client);
- g_object_unref (G_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
+ remove_uri_to_load (str_uri);
}
@@ -367,40 +271,6 @@ alarm_notify_new (void)
return an;
}
-static gboolean
-retry_timeout_cb (gpointer data)
-{
- LoadedClient *lc = data;
- char *str_uri;
-
- if (cal_client_get_load_state (lc->client) != CAL_CLIENT_LOAD_LOADED) {
- str_uri = e_uri_to_string (lc->uri, FALSE);
- cal_client_open_calendar (lc->client, str_uri, FALSE);
-
- g_free (str_uri);
- }
-
- return FALSE;
-}
-
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- LoadedClient *lc = (LoadedClient *) data;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- add_uri_to_load (lc->uri);
- alarm_queue_add_client (client);
- lc->timeout_id = -1;
- }
- else {
- remove_uri_to_load (lc->uri);
-
- /* we set a timeout of 5 mins before retrying */
- lc->timeout_id = g_timeout_add (300000, (GSourceFunc) retry_timeout_cb, lc);
- }
-}
-
/**
* alarm_notify_add_calendar:
* @an: An alarm notification service.
@@ -418,10 +288,7 @@ alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_a
CORBA_Environment *ev)
{
AlarmNotifyPrivate *priv;
- EUri *uri;
CalClient *client;
- LoadedClient *lc;
- gpointer lc_ptr, s_ptr;
g_return_if_fail (an != NULL);
g_return_if_fail (IS_ALARM_NOTIFY (an));
@@ -430,49 +297,23 @@ alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_a
priv = an->priv;
- uri = e_uri_new (str_uri);
- if (!uri) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI,
- NULL);
+ /* See if we already know about this uri */
+ if (g_hash_table_lookup (priv->uri_client_hash, str_uri))
return;
- }
- if (g_hash_table_lookup_extended (priv->uri_client_hash, str_uri, &s_ptr, &lc_ptr)) {
- lc = lc_ptr;
- lc->refcount++;
- } else {
- client = cal_client_new ();
-
- if (client) {
- /* we only add the URI to load_afterwards if we open it
- correctly */
- lc = g_new (LoadedClient, 1);
- lc->client = client;
- lc->uri = uri;
- lc->refcount = 1;
- lc->timeout_id = -1;
-
-
- g_signal_connect (G_OBJECT (client), "cal_opened",
- G_CALLBACK (cal_opened_cb),
- lc);
-
- if (cal_client_open_calendar (client, str_uri, FALSE)) {
- g_hash_table_insert (priv->uri_client_hash,
- g_strdup (str_uri), lc);
- } else {
- g_free (lc);
- g_object_unref (G_OBJECT (client));
- client = NULL;
- }
- } else {
- e_uri_free (uri);
-
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError,
- NULL);
- return;
+ client = cal_client_new (str_uri, CALOBJ_TYPE_EVENT);
+
+ if (client) {
+ if (cal_client_open (client, FALSE, NULL)) {
+ add_uri_to_load (str_uri);
+
+ g_hash_table_insert (priv->uri_client_hash,
+ g_strdup (str_uri), client);
}
+ } else {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError,
+ NULL);
+ return;
}
}
diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c
index cb792e466f..cee17bd97e 100644
--- a/calendar/gui/alarm-notify/alarm-queue.c
+++ b/calendar/gui/alarm-notify/alarm-queue.c
@@ -227,7 +227,7 @@ remove_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id,
if (remove_alarm) {
cqa->expecting_update = TRUE;
cal_client_discard_alarm (cqa->parent_client->client, cqa->alarms->comp,
- qa->instance->auid);
+ qa->instance->auid, NULL);
cqa->expecting_update = FALSE;
}
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index c0d1b3c589..77305098bc 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -59,6 +59,7 @@
#include "goto.h"
#include "print.h"
#include "dialogs/cal-prefs-dialog.h"
+#include "dialogs/new-calendar.h"
#include "itip-utils.h"
#include "evolution-shell-component-utils.h"
@@ -73,6 +74,68 @@ typedef struct {
guint taskpad_focused : 1;
} FocusData;
+static void
+file_new_calendar_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ new_calendar_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
+}
+
+static void
+file_new_appointment_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+static void
+file_new_event_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
+}
+
+static void
+file_new_meeting_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
+}
+
+static void
+file_new_task_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ gnome_calendar_new_task (gcal);
+}
+
/* Prints the calendar at its current view and time range */
static void
print (GnomeCalendar *gcal, gboolean preview)
@@ -335,12 +398,10 @@ publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
start = time_day_begin_with_zone (start, utc);
end = time_add_week_with_zone (start, 6, utc);
+ /* FIXME Should we aggregate the data? */
client_list = e_cal_model_get_client_list (gnome_calendar_get_calendar_model (gcal));
for (cl = client_list; cl != NULL; cl = cl->next) {
- GList *tmp_comp_list;
-
- tmp_comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (tmp_comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -599,19 +660,42 @@ control_util_show_settings (GnomeCalendar *gcal)
* is FALSE, all will be disabled. Otherwise, the currently-selected number of
* events will be used.
*/
-static void
-sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable)
+void
+calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable)
{
BonoboUIComponent *uic;
+ ECalViewEvent *event;
+ GList *list;
int n_selected;
- gboolean read_only, has_recurrences;
+ GtkWidget *view;
+ CalClient *cal_client;
+ gboolean read_only = FALSE, has_recurrences;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
- n_selected = enable ? gnome_calendar_get_num_events_selected (gcal) : 0;
- read_only = cal_client_is_read_only (e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal)));
+ view = gnome_calendar_get_current_view_widget (gcal);
+ list = e_cal_view_get_selected_events (E_CAL_VIEW (view));
+
+ n_selected = enable ? g_list_length (list) : 0;
+ event = (ECalViewEvent *) list ? list->data : NULL;
+ if (event) {
+ cal_client_is_read_only (event->comp_data->client, &read_only, NULL);
+ } else {
+ cal_client = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal));
+ if (cal_client)
+ cal_client_is_read_only (cal_client, &read_only, NULL);
+ else
+ read_only = TRUE;
+ }
+
+ bonobo_ui_component_set_prop (uic, "/commands/NewAppointment", "sensitive",
+ read_only ? "0" : "1", NULL);
+ bonobo_ui_component_set_prop (uic, "/commands/NewAllDayEvent", "sensitive",
+ read_only ? "0" : "1", NULL);
+ bonobo_ui_component_set_prop (uic, "/commands/NewMeeting", "sensitive",
+ read_only ? "0" : "1", NULL);
bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",
NULL);
@@ -628,19 +712,8 @@ sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboole
/* occurrence-related menu items */
has_recurrences = FALSE;
if (n_selected > 0 && !read_only) {
- ECalViewEvent *event;
- GList *list;
- GtkWidget *view;
-
- view = gnome_calendar_get_current_view_widget (gcal);
- list = e_cal_view_get_selected_events (E_CAL_VIEW (view));
if (list) {
event = (ECalViewEvent *) list->data;
- g_list_free (list);
- } else
- event = NULL;
-
- if (event) {
if (cal_util_component_has_recurrences (event->comp_data->icalcomp))
has_recurrences = TRUE;
}
@@ -652,6 +725,10 @@ sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboole
bonobo_ui_component_set_prop (uic, "/commands/DeleteAllOccurrences", "sensitive",
has_recurrences ? "1" : "0",
NULL);
+
+ /* free memory */
+ if (list)
+ g_list_free (list);
}
/* Sensitizes the UI Component menu/toolbar tasks commands based on the number
@@ -663,14 +740,21 @@ sensitize_taskpad_commands (GnomeCalendar *gcal, BonoboControl *control, gboolea
{
BonoboUIComponent *uic;
int n_selected;
- gboolean read_only;
+ CalClient *cal_client;
+ gboolean read_only = TRUE;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
n_selected = enable ? gnome_calendar_get_num_tasks_selected (gcal) : 0;
- read_only = cal_client_is_read_only (gnome_calendar_get_task_pad_cal_client (gcal));
-
+ cal_client = gnome_calendar_get_task_pad_cal_client (gcal);
+ if (cal_client)
+ cal_client_is_read_only (cal_client, &read_only, NULL);
+ else
+ read_only = TRUE;
+
+ bonobo_ui_component_set_prop (uic, "/commands/NewTask", "sensitive",
+ read_only ? "0" : "1", NULL);
bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",
NULL);
@@ -705,7 +789,7 @@ gcal_calendar_selection_changed_cb (GnomeCalendar *gcal, gpointer data)
control = BONOBO_CONTROL (data);
- sensitize_calendar_commands (gcal, control, TRUE);
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
}
/* Callback used when the selection in the taskpad changes */
@@ -734,13 +818,13 @@ gcal_calendar_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
if (in) {
g_signal_connect (gcal, "calendar_selection_changed",
G_CALLBACK (gcal_calendar_selection_changed_cb), control);
- sensitize_calendar_commands (gcal, control, TRUE);
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
focus->calendar_focused = TRUE;
} else if (focus->calendar_focused) {
gtk_signal_disconnect_by_func (GTK_OBJECT (gcal),
G_CALLBACK (gcal_calendar_selection_changed_cb),
control);
- sensitize_calendar_commands (gcal, control, FALSE);
+ calendar_control_sensitize_calendar_commands (control, gcal, FALSE);
focus->calendar_focused = FALSE;
}
}
@@ -779,6 +863,11 @@ gcal_taskpad_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
static BonoboUIVerb verbs [] = {
+ BONOBO_UI_VERB ("NewCalendar", file_new_calendar_cb),
+ BONOBO_UI_VERB ("NewAppointment", file_new_appointment_cb),
+ BONOBO_UI_VERB ("NewAllDayEvent", file_new_event_cb),
+ BONOBO_UI_VERB ("NewMeeting", file_new_meeting_cb),
+ BONOBO_UI_VERB ("NewTask", file_new_task_cb),
BONOBO_UI_VERB ("CalendarPrint", file_print_cb),
BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb),
@@ -808,11 +897,15 @@ static BonoboUIVerb verbs [] = {
static EPixmap pixmaps [] =
{
- E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"),
- E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"),
- E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"),
- E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"),
- E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"),
+ E_PIXMAP ("/commands/NewAppointment", "new_appointment.xpm"),
+ E_PIXMAP ("/commands/NewAllDayEvent", "new_all_day_event.png"),
+ E_PIXMAP ("/commands/NewMeeting", "meeting-request-16.png"),
+ E_PIXMAP ("/commands/NewTask", "new_task-16.png"),
+ E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"),
+ E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"),
+ E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"),
+ E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"),
+ E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"),
E_PIXMAP_END
};
@@ -855,7 +948,7 @@ calendar_control_activate (BonoboControl *control,
g_signal_connect (gcal, "taskpad_focus_change",
G_CALLBACK (gcal_taskpad_focus_change_cb), control);
- sensitize_calendar_commands (gcal, control, FALSE);
+ calendar_control_sensitize_calendar_commands (control, gcal, FALSE);
sensitize_taskpad_commands (gcal, control, FALSE);
bonobo_ui_component_thaw (uic, NULL);
diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h
index 6f418799d2..3e74074140 100644
--- a/calendar/gui/calendar-commands.h
+++ b/calendar/gui/calendar-commands.h
@@ -38,6 +38,8 @@ GnomeCalendar *new_calendar (void);
void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal);
void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal);
+void calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable);
+
void calendar_goto_today (GnomeCalendar *gcal);
void calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control);
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 98f0964cc4..3e8782f45b 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.c
+/* calendar-component.c
*
- * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -20,752 +20,269 @@
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
+#ifdef CONFIG_H
#include <config.h>
+#endif
-#include <errno.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomevfs/gnome-vfs-types.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-directory.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-exception.h>
-
-#include "evolution-shell-component.h"
-#include "calendar-offline-handler.h"
#include "calendar-component.h"
-#include "tasks-control.h"
#include "control-factory.h"
-#include "calendar-config.h"
-#include "tasks-control.h"
-#include "e-comp-editor-registry.h"
-#include "dialogs/comp-editor.h"
-
-
-/* OAFIID for the component. */
-#define COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent"
-
-/* Folder type IDs */
-#define FOLDER_CALENDAR "calendar"
-#define FOLDER_TASKS "tasks"
-#define FOLDER_PUBLIC_CALENDAR "calendar/public"
-#define FOLDER_PUBLIC_TASKS "tasks/public"
-
-/* IDs for user creatable items */
-#define CREATE_EVENT_ID "event"
-#define CREATE_ALLDAY_EVENT_ID "allday-event"
-#define CREATE_MEETING_ID "meeting"
-#define CREATE_TASK_ID "task"
-
-char *evolution_dir = NULL;
-EvolutionShellClient *global_shell_client = NULL;
-extern ECompEditorRegistry *comp_editor_registry;
-
-static const EvolutionShellComponentFolderType folder_types[] = {
- { FOLDER_CALENDAR,
- "evolution-calendar.png",
- N_("Calendar"),
- N_("Folder containing appointments and events"),
- TRUE, NULL, NULL },
- { FOLDER_PUBLIC_CALENDAR,
- "evolution-calendar.png",
- N_("Public Calendar"),
- N_("Public folder containing appointments and events"),
- FALSE, NULL, NULL },
- { FOLDER_TASKS,
- "evolution-tasks.png",
- N_("Tasks"),
- N_("Folder containing to-do items"),
- TRUE, NULL, NULL },
- { FOLDER_PUBLIC_TASKS,
- "evolution-tasks.png",
- N_("Public Tasks"),
- N_("Public folder containing to-do items"),
- FALSE, NULL, NULL },
- { NULL, NULL }
-};
+#include "gnome-cal.h"
+#include "migration.h"
-
-
-static inline gboolean
-type_is_calendar (const char *type)
-{
- return !strcmp (type, FOLDER_CALENDAR) ||
- !strcmp (type, FOLDER_PUBLIC_CALENDAR);
-}
+#include "widgets/misc/e-source-selector.h"
-static inline gboolean
-type_is_tasks (const char *type)
-{
- return !strcmp (type, FOLDER_TASKS) ||
- !strcmp (type, FOLDER_PUBLIC_TASKS);
-}
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-i18n.h>
+#include <gal/util/e-util.h>
-/* EvolutionShellComponent methods and signals. */
+#include <errno.h>
-static EvolutionShellComponentResult
-create_view (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const char *view_info,
- BonoboControl **control_return,
- void *closure)
-{
- BonoboControl *control;
-
- if (type_is_calendar (type)) {
- control = control_factory_new_control ();
- if (!control)
- return EVOLUTION_SHELL_COMPONENT_CORBAERROR;
- } else if (type_is_tasks (type)) {
- control = tasks_control_new ();
- if (!control)
- return EVOLUTION_SHELL_COMPONENT_CORBAERROR;
- } else {
- return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE;
- }
- bonobo_control_set_property (control, NULL, "folder_uri", TC_CORBA_string, physical_uri, NULL);
- if (type_is_calendar (type) && *view_info)
- bonobo_control_set_property (control, NULL, "view", TC_CORBA_string, view_info, NULL);
+#define PARENT_TYPE bonobo_object_get_type ()
+static BonoboObjectClass *parent_class = NULL;
- *control_return = control;
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
+struct _CalendarComponentPrivate {
+ char *config_directory;
-static void
-create_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- CORBA_Environment ev;
- GnomeVFSURI *uri;
+ GConfClient *gconf_client;
+ ESourceList *source_list;
+};
- CORBA_exception_init (&ev);
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free (&ev);
- return;
- }
+/* Utility functions. */
- uri = gnome_vfs_uri_new (physical_uri);
- if (uri) {
- /* we don't need to do anything */
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_OK, &ev);
- gnome_vfs_uri_unref (uri);
- }
- else {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- }
+static void
+load_uri_for_source (ESource *source, BonoboControl *view_control)
+{
+ GnomeCalendar *gcal;
+ char *uri = e_source_get_uri (source);
- CORBA_exception_free (&ev);
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (view_control);
+ gnome_calendar_add_event_uri (gcal, uri);
+ g_free (uri);
}
-/* Asks the alarm daemon to stop monitoring the specified URI */
static void
-stop_alarms (GnomeVFSURI *uri)
+load_uri_for_selection (ESourceSelector *selector, BonoboControl *view_control)
{
- char *str_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_AlarmNotify an;
-
- /* Activate the alarm notification service */
-
- CORBA_exception_init (&ev);
- an = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("stop_alarms(): Could not activate the alarm notification service");
- CORBA_exception_free (&ev);
- return;
- }
- CORBA_exception_free (&ev);
-
- /* Ask the service to remove the URI from its list of calendars */
-
- str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
- g_assert (str_uri != NULL);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev);
- g_free (str_uri);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI)) {
- g_message ("stop_alarms(): Invalid URI reported from the alarm notification service");
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound)) {
- /* This is OK; the service may not have loaded that calendar */
- } else if (BONOBO_EX (&ev)) {
- g_message ("stop_alarms(): Could not issue the removeCalendar request");
- }
+ GSList *selection, *l;
- CORBA_exception_free (&ev);
-
- /* Get rid of the service */
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (an, &ev);
- if (BONOBO_EX (&ev))
- g_message ("stop_alarms(): Could not unref the alarm notification service");
- CORBA_exception_free (&ev);
+ selection = e_source_selector_get_selection (selector);
+ for (l = selection; l; l = l->next) {
+ ESource *selected_source = l->data;
+
+ load_uri_for_source (selected_source, view_control);
+ }
}
+/* Callbacks. */
static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+source_selection_changed_callback (ESourceSelector *selector,
+ BonoboControl *view_control)
{
- GnomeVFSURI *dir_uri, *data_uri, *backup_uri;
- GnomeVFSResult data_result, backup_result;
-
- /* check type */
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener of "
- "an unsupported folder type");
+
+ load_uri_for_selection (selector, view_control);
+}
- CORBA_exception_free (&ev);
- return;
- }
+static void
+primary_source_selection_changed_callback (ESourceSelector *selector,
+ BonoboControl *view_control)
+{
+ ESource *source;
+ GnomeCalendar *gcal;
+ ECalModel *model;
+ CalClient *client;
- /* check URI */
- dir_uri = gnome_vfs_uri_new (physical_uri);
- if (!dir_uri) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- CORBA_exception_free (&ev);
+ source = e_source_selector_peek_primary_selection (selector);
+ if (!source)
return;
- }
- /* Compute the URIs of the appropriate files */
-
- if (type_is_calendar (type)) {
- data_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics");
- backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics~");
- } else if (type_is_tasks (type)) {
- data_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics");
- backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics~");
- } else {
- g_assert_not_reached ();
+ /* set the default client on the GnomeCalendar */
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (view_control);
+ if (!GNOME_IS_CALENDAR (gcal))
return;
- }
-
- if (!data_uri || !backup_uri) {
- CORBA_Environment ev;
-
- g_message ("remove_folder(): Could not generate the data/backup URIs");
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener "
- "of an invalid URI");
-
- CORBA_exception_free (&ev);
-
- goto out;
- }
-
- /* Ask the alarm daemon to stop monitoring this URI */
-
- stop_alarms (data_uri);
-
- /* Delete the data and backup files; the shell will take care of the rest */
-
- data_result = gnome_vfs_unlink_from_uri (data_uri);
- backup_result = gnome_vfs_unlink_from_uri (backup_uri);
-
- if ((data_result == GNOME_VFS_OK || data_result == GNOME_VFS_ERROR_NOT_FOUND)
- && (backup_result == GNOME_VFS_OK || backup_result == GNOME_VFS_ERROR_NOT_FOUND)) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_OK,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener about success");
-
- CORBA_exception_free (&ev);
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener about failure");
-
- CORBA_exception_free (&ev);
- }
- out:
-
- gnome_vfs_uri_unref (dir_uri);
-
- if (data_uri)
- gnome_vfs_uri_unref (data_uri);
-
- if (backup_uri)
- gnome_vfs_uri_unref (backup_uri);
+ model = gnome_calendar_get_calendar_model (gcal);
+ client = e_cal_model_get_client_for_uri (model, e_source_get_uri (source));
+ if (client)
+ gnome_calendar_set_default_client (gcal, client);
}
-static GNOME_Evolution_ShellComponentListener_Result
-xfer_file (GnomeVFSURI *base_src_uri,
- GnomeVFSURI *base_dest_uri,
- const char *file_name,
- int remove_source)
-{
- GnomeVFSURI *src_uri, *dest_uri;
- GnomeVFSHandle *hin, *hout;
- GnomeVFSResult result;
- GnomeVFSFileInfo file_info;
- GnomeVFSFileSize size;
- char *buffer;
-
- src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name);
-
- result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ);
- if (result == GNOME_VFS_ERROR_NOT_FOUND) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */
- }
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
-
- result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
-
- dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name);
-
- result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+/* GObject methods. */
- /* write source file to destination file */
- buffer = g_malloc (file_info.size);
- result = gnome_vfs_read (hin, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+static void
+impl_dispose (GObject *object)
+{
+ CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
- result = gnome_vfs_write (hout, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
}
- if (remove_source) {
- char *text_uri;
-
- /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */
-
- text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE);
- result = gnome_vfs_unlink (text_uri);
- g_free (text_uri);
+ if (priv->gconf_client != NULL) {
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
}
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
-
- return GNOME_Evolution_ShellComponentListener_OK;
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static void
-xfer_folder (EvolutionShellComponent *shell_component,
- const char *source_physical_uri,
- const char *destination_physical_uri,
- const char *type,
- gboolean remove_source,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+impl_finalize (GObject *object)
{
- CORBA_Environment ev;
- GnomeVFSURI *src_uri;
- GnomeVFSURI *dest_uri;
- GnomeVFSResult result;
- char *filename, *backup_filename;
-
- CORBA_exception_init (&ev);
-
- /* check type */
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- /* check URIs */
- src_uri = gnome_vfs_uri_new (source_physical_uri);
- dest_uri = gnome_vfs_uri_new (destination_physical_uri);
- if (!src_uri || ! dest_uri) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- CORBA_exception_free (&ev);
- return;
- }
-
- if (type_is_calendar (type)) {
- filename = "calendar.ics";
- backup_filename = "calendar.ics~";
- } else if (type_is_tasks (type)) {
- filename = "tasks.ics";
- backup_filename = "tasks.ics~";
- } else {
- g_assert_not_reached ();
- return;
- }
-
- result = xfer_file (src_uri, dest_uri, filename, remove_source);
- if (result == GNOME_Evolution_ShellComponentListener_OK)
- result = xfer_file (src_uri, dest_uri, backup_filename, remove_source);
-
- GNOME_Evolution_ShellComponentListener_notifyResult (listener, result, &ev);
+ CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
+ g_free (priv->config_directory);
+ g_free (priv);
- CORBA_exception_free (&ev);
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-static gboolean
-request_quit (EvolutionShellComponent *shell_component, void *closure)
-{
- return e_comp_editor_registry_close_all (comp_editor_registry);
-}
-static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
-{
- if (evolution_dir)
- g_free (evolution_dir);
- evolution_dir = g_strdup (evolution_homedir);
- global_shell_client = shell_client;
-}
+/* Evolution::Component CORBA methods. */
static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
+impl_createControls (PortableServer_Servant servant,
+ Bonobo_Control *corba_sidebar_control,
+ Bonobo_Control *corba_view_control,
+ CORBA_Environment *ev)
{
- global_shell_client = NULL;
-}
+ CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
+ GtkWidget *selector;
+ GtkWidget *selector_scrolled_window;
+ BonoboControl *sidebar_control;
+ BonoboControl *view_control;
-/* Computes the final URI for a calendar component */
-static char *
-get_data_uri (const char *uri, CalComponentVType vtype)
-{
- if (uri) {
- if (*uri != '/' && strncmp (uri, "file:", 5) != 0)
- return g_strdup (uri);
-
- if (vtype == CAL_COMPONENT_EVENT)
- return cal_util_expand_uri ((char *) uri, FALSE);
- else if (vtype == CAL_COMPONENT_TODO)
- return cal_util_expand_uri ((char *) uri, TRUE);
- else
- g_assert_not_reached ();
- } else {
- if (vtype == CAL_COMPONENT_EVENT)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Calendar/calendar.ics");
- else if (vtype == CAL_COMPONENT_TODO)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Tasks/tasks.ics");
- else
- g_assert_not_reached ();
- }
+ selector = e_source_selector_new (calendar_component->priv->source_list);
+ gtk_widget_show (selector);
- return NULL;
-}
+ selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (selector_scrolled_window), selector);
+ gtk_widget_show (selector_scrolled_window);
-/* Creates a calendar component at a specified URI. If the URI is NULL then it
- * uses the default folder for that type of component.
- */
-static void
-create_component (const char *uri, GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- char *real_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CompEditorFactory factory;
- CalComponentVType vtype;
-
- switch (type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT:
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT:
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING:
- vtype = CAL_COMPONENT_EVENT;
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- vtype = CAL_COMPONENT_TODO;
- break;
- default:
- g_assert_not_reached ();
- return;
- }
+ sidebar_control = bonobo_control_new (selector_scrolled_window);
- real_uri = get_data_uri (uri, vtype);
+ view_control = control_factory_new_control ();
- /* Get the factory */
+ g_signal_connect_object (selector, "selection_changed",
+ G_CALLBACK (source_selection_changed_callback),
+ G_OBJECT (view_control), 0);
+ g_signal_connect_object (selector, "primary_selection_changed",
+ G_CALLBACK (primary_source_selection_changed_callback),
+ G_OBJECT (view_control), 0);
- CORBA_exception_init (&ev);
- factory = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory",
- 0, NULL, &ev);
+ load_uri_for_selection (E_SOURCE_SELECTOR (selector), view_control);
- if (BONOBO_EX (&ev)) {
- g_message ("create_component(): Could not activate the component editor factory");
- CORBA_exception_free (&ev);
- g_free (real_uri);
- return;
- }
- CORBA_exception_free (&ev);
+ *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev);
+ *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev);
+}
- /* Create the item */
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev);
+/* Initialization. */
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Exception while creating the component");
+static void
+calendar_component_class_init (CalendarComponentClass *class)
+{
+ POA_GNOME_Evolution_Component__epv *epv = &class->epv;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
- CORBA_exception_free (&ev);
- g_free (real_uri);
+ parent_class = g_type_class_peek_parent (class);
- /* Get rid of the factory */
+ epv->createControls = impl_createControls;
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (factory, &ev);
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Could not unref the calendar component factory");
+ object_class->dispose = impl_dispose;
+ object_class->finalize = impl_finalize;
- CORBA_exception_free (&ev);
+ epv->createControls = impl_createControls;
}
-/* Callback used when we must create a user-creatable item */
static void
-sc_user_create_new_item_cb (EvolutionShellComponent *shell_component,
- const char *id,
- const char *parent_folder_physical_uri,
- const char *parent_folder_type)
+calendar_component_init (CalendarComponent *component)
{
- char *tmp_uri;
-
- if (strcmp (id, CREATE_EVENT_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- g_free (tmp_uri);
- }
- } else if (strcmp (id, CREATE_ALLDAY_EVENT_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- g_free (tmp_uri);
- }
- } else if (strcmp (id, CREATE_MEETING_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- g_free (tmp_uri);
+ CalendarComponentPrivate *priv;
+ GSList *groups;
+
+ priv = g_new0 (CalendarComponentPrivate, 1);
+
+ priv->config_directory = g_build_filename (g_get_home_dir (),
+ ".evolution", "calendar", "config",
+ NULL);
+
+ /* EPFIXME: Should use a custom one instead? Also we should add
+ * calendar_component_peek_gconf_client(). */
+ priv->gconf_client = gconf_client_get_default ();
+
+ priv->source_list = e_source_list_new_for_gconf (priv->gconf_client,
+ "/apps/evolution/calendar/sources");
+
+ /* create default calendars if there are no groups */
+ groups = e_source_list_peek_groups (priv->source_list);
+ if (!groups) {
+ ESourceGroup *group;
+ ESource *source;
+ char *base_uri, *new_dir;
+
+ /* create the source group */
+ base_uri = g_build_filename (g_get_home_dir (),
+ "/.evolution/calendar/local/OnThisComputer/",
+ NULL);
+ group = e_source_group_new (_("On This Computer"), base_uri);
+ e_source_list_add_group (priv->source_list, group, -1);
+
+ /* migrate calendars from older setup */
+ if (!migrate_old_calendars (group)) {
+ /* create default calendars */
+ new_dir = g_build_filename (base_uri, "Personal/", NULL);
+ if (!e_mkdir_hier (new_dir, 0700)) {
+ source = e_source_new (_("Personal"), "Personal");
+ e_source_group_add_source (group, source, -1);
+ }
+ g_free (new_dir);
+
+ new_dir = g_build_filename (base_uri, "Work/", NULL);
+ if (!e_mkdir_hier (new_dir, 0700)) {
+ source = e_source_new (_("Work"), "Work");
+ e_source_group_add_source (group, source, -1);
+ }
+ g_free (new_dir);
}
- } else if (strcmp (id, CREATE_TASK_ID) == 0) {
- if (type_is_tasks (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- else {
- tmp_uri = calendar_config_default_tasks_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- g_free (tmp_uri);
- }
- } else
- g_assert_not_reached ();
-}
-
-/* The factory function. */
-
-static void
-add_creatable_item (EvolutionShellComponent *shell_component,
- const char *id,
- const char *description,
- const char *menu_description,
- const char *tooltip,
- const char *folder_type,
- char menu_shortcut,
- const char *icon_name)
-{
- char *icon_path;
- GdkPixbuf *icon;
-
- if (icon_name == NULL) {
- icon_path = NULL;
- icon = NULL;
- } else {
- icon_path = g_concat_dir_and_file (EVOLUTION_IMAGESDIR, icon_name);
- icon = gdk_pixbuf_new_from_file (icon_path, NULL);
+ g_free (base_uri);
}
- evolution_shell_component_add_user_creatable_item (shell_component,
- id,
- description,
- menu_description,
- tooltip,
- folder_type,
- menu_shortcut,
- icon);
-
- if (icon != NULL)
- gdk_pixbuf_unref (icon);
- g_free (icon_path);
+ component->priv = priv;
}
-static BonoboObject *
-create_object (void)
-{
- EvolutionShellComponent *shell_component;
- CalendarOfflineHandler *offline_handler;
-
- shell_component = evolution_shell_component_new (folder_types,
- NULL,
- create_view,
- create_folder,
- remove_folder,
- xfer_folder,
- NULL, /* populate_folder_context_menu_fn */
- NULL, /* unpopulate_folder_context_menu_fn */
- NULL, /* get_dnd_selection_fn */
- request_quit,
- NULL /* closure */);
-
- /* Offline handler */
- offline_handler = calendar_offline_handler_new ();
- bonobo_object_add_interface (BONOBO_OBJECT (shell_component),
- BONOBO_OBJECT (offline_handler));
-
- g_signal_connect (shell_component, "owner_set", G_CALLBACK (owner_set_cb), NULL);
- g_signal_connect (shell_component, "owner_unset", G_CALLBACK (owner_unset_cb), NULL);
-
- /* User creatable items */
- add_creatable_item (shell_component, CREATE_EVENT_ID,
- _("New appointment"), _("_Appointment"),
- _("Create a new appointment"),
- FOLDER_CALENDAR, 'a', "new_appointment.xpm");
+/* Public API. */
- add_creatable_item (shell_component, CREATE_MEETING_ID,
- _("New meeting"), _("M_eeting"),
- _("Create a new meeting request"),
- FOLDER_CALENDAR, 'e', "meeting-request-16.png");
-
- add_creatable_item (shell_component, CREATE_TASK_ID,
- _("New task"), _("_Task"),
- _("Create a new task"),
- FOLDER_TASKS, 't', "new_task-16.png");
+CalendarComponent *
+calendar_component_peek (void)
+{
+ static CalendarComponent *component = NULL;
- add_creatable_item (shell_component, CREATE_ALLDAY_EVENT_ID,
- _("New All Day Appointment"), _("All _Day Appointment"),
- _("Create a new all-day appointment"),
- FOLDER_CALENDAR, 'd', "new_all_day_event.png");
+ if (component == NULL) {
+ component = g_object_new (calendar_component_get_type (), NULL);
- g_signal_connect (shell_component, "user_create_new_item",
- G_CALLBACK (sc_user_create_new_item_cb), NULL);
+ if (e_mkdir_hier (calendar_component_peek_config_directory (component), 0777) != 0) {
+ g_warning ("Cannot create directory %s: %s",
+ calendar_component_peek_config_directory (component),
+ g_strerror (errno));
+ g_object_unref (component);
+ component = NULL;
+ }
+ }
- return BONOBO_OBJECT (shell_component);
+ return component;
}
-
-BonoboObject *
-calendar_component_get_object (void)
+const char *
+calendar_component_peek_config_directory (CalendarComponent *component)
{
- static BonoboObject *object = NULL;
+ return component->priv->config_directory;
+}
- if (object != NULL) {
- bonobo_object_ref (BONOBO_OBJECT (object));
- } else {
- object = create_object ();
- g_object_add_weak_pointer (G_OBJECT (object), (void *) &object);
- }
- return object;
-}
+BONOBO_TYPE_FUNC_FULL (CalendarComponent, GNOME_Evolution_Component, PARENT_TYPE, calendar_component)
diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h
index 2d94920adc..96630add5f 100644
--- a/calendar/gui/calendar-component.h
+++ b/calendar/gui/calendar-component.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.h
+/* calendar-component.h
*
- * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -20,13 +20,47 @@
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
-#ifndef _COMPONENT_FACTORY_H_
-#define _COMPONENT_FACTORY_H_
+#ifndef _CALENDAR_COMPONENT_H_
+#define _CALENDAR_COMPONENT_H_
+
#include <bonobo/bonobo-object.h>
-extern char *evolution_dir;
+#include "Evolution.h"
+#include "e-util/e-source-list.h"
+
+
+#define CALENDAR_TYPE_COMPONENT (calendar_component_get_type ())
+#define CALENDAR_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALENDAR_TYPE_COMPONENT, CalendarComponent))
+#define CALENDAR_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_COMPONENT, CalendarComponentClass))
+#define CALENDAR_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALENDAR_TYPE_COMPONENT))
+#define CALENDAR_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_COMPONENT))
+
+
+typedef struct _CalendarComponent CalendarComponent;
+typedef struct _CalendarComponentPrivate CalendarComponentPrivate;
+typedef struct _CalendarComponentClass CalendarComponentClass;
+
+struct _CalendarComponent {
+ BonoboObject parent;
+
+ CalendarComponentPrivate *priv;
+};
+
+struct _CalendarComponentClass {
+ BonoboObjectClass parent_class;
+
+ POA_GNOME_Evolution_Component__epv epv;
+};
+
+
+GType calendar_component_get_type (void);
+
+CalendarComponent *calendar_component_peek (void);
+
+const char *calendar_component_peek_config_directory (CalendarComponent *component);
+
+ESourceList *calendar_component_peek_source_list (CalendarComponent *component);
-BonoboObject *calendar_component_get_object (void);
-#endif /* _COMPONENT_FACTORY_H_ */
+#endif /* _CALENDAR_COMPONENT_H_ */
diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c
index 458f951d9a..ff30299746 100644
--- a/calendar/gui/calendar-offline-handler.c
+++ b/calendar/gui/calendar-offline-handler.c
@@ -29,6 +29,7 @@
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-i18n.h>
#include <gal/util/e-util.h>
#include "e-util/e-url.h"
#include <cal-client/cal-client.h>
@@ -180,13 +181,16 @@ backend_go_offline (gpointer data, gpointer user_data)
char *uri = data;
CalClient *client;
gboolean success;
+ GError *error = NULL;
- client = cal_client_new ();
+ client = cal_client_new (uri, CALOBJ_TYPE_ANY);
g_signal_connect (client, "cal_opened", G_CALLBACK (backend_cal_opened_offline), offline_handler);
- success = cal_client_open_calendar (client, uri, TRUE);
+ success = cal_client_open (client, TRUE, &error);
if (!success) {
+ g_warning (_("backend_go_offline(): %s"), error->message);
update_offline (offline_handler);
g_object_unref (client);
+ g_error_free (error);
return;
}
}
@@ -198,13 +202,16 @@ backend_go_online (gpointer data, gpointer user_data)
char *uri = data;
CalClient *client;
gboolean success;
+ GError *error = NULL;
- client = cal_client_new ();
+ client = cal_client_new (uri, CALOBJ_TYPE_ANY);
g_signal_connect (G_OBJECT (client), "cal_opened",
G_CALLBACK (backend_cal_opened_online), offline_handler);
- success = cal_client_open_calendar (client, uri, TRUE);
+ success = cal_client_open (client, TRUE, &error);
if (!success) {
+ g_warning (_("backend_go_online(): %s"), error->message);
g_object_unref (G_OBJECT (client));
+ g_error_free (error);
return;
}
}
@@ -319,7 +326,8 @@ calendar_offline_handler_init (CalendarOfflineHandler *offline_handler)
priv = g_new (CalendarOfflineHandlerPrivate, 1);
offline_handler->priv = priv;
- priv->client = cal_client_new ();
+ /* FIXME: what URI to use? */
+ priv->client = cal_client_new ("", CALOBJ_TYPE_ANY);
priv->listener_interface = CORBA_OBJECT_NIL;
priv->is_offline = FALSE;
}
diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c
index f76e0d4f03..7b7dcb4c87 100644
--- a/calendar/gui/comp-editor-factory.c
+++ b/calendar/gui/comp-editor-factory.c
@@ -241,39 +241,26 @@ edit_existing (OpenClient *oc, const char *uid)
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
CompEditor *editor;
CalComponentVType vtype;
g_assert (oc->open);
/* Get the object */
+ if (!cal_client_get_object (oc->client, uid, NULL, &icalcomp, NULL)) {
+ /* FIXME Better error handling */
+ g_warning (G_STRLOC ": Syntax error while getting component `%s'", uid);
- status = cal_client_get_object (oc->client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object disappeared from the server */
- return;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("edit_exiting(): Syntax error while getting component `%s'", uid);
return;
-
- default:
- g_assert_not_reached ();
+ }
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ g_object_unref (comp);
+ icalcomponent_free (icalcomp);
return;
}
-
+
/* Create the appropriate type of editor */
vtype = cal_component_get_vtype (comp);
@@ -405,13 +392,15 @@ resolve_pending_requests (OpenClient *oc)
factory = oc->factory;
priv = factory->priv;
- g_assert (oc->pending != NULL);
+ if (!oc->pending)
+ return;
/* Set the default timezone in the backend. */
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
if (zone)
- cal_client_set_default_timezone (oc->client, zone);
+ /* FIXME Error handling? */
+ cal_client_set_default_timezone (oc->client, zone, NULL);
for (l = oc->pending; l; l = l->next) {
Request *request;
@@ -501,10 +490,11 @@ open_client (CompEditorFactory *factory, const char *uristr)
CompEditorFactoryPrivate *priv;
CalClient *client;
OpenClient *oc;
+ GError *error = NULL;
priv = factory->priv;
- client = cal_client_new ();
+ client = cal_client_new (uristr, CALOBJ_TYPE_ANY);
if (!client)
return NULL;
@@ -522,10 +512,12 @@ open_client (CompEditorFactory *factory, const char *uristr)
g_hash_table_insert (priv->uri_client_hash, oc->uri, oc);
- if (!cal_client_open_calendar (oc->client, uristr, FALSE)) {
+ if (!cal_client_open (oc->client, FALSE, &error)) {
+ g_warning (_("open_client(): %s"), error->message);
g_free (oc->uri);
g_object_unref (oc->client);
g_free (oc);
+ g_error_free (error);
return NULL;
}
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 28bc66bd54..aceff667c2 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -95,7 +95,6 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
CalClient *client,
icaltimezone *zone)
{
- CalClientGetStatus status;
CalComponentDateTime start_datetime, end_datetime;
const char *tzid;
gboolean retval = FALSE;
@@ -143,10 +142,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
/* If the TZIDs differ, we have to compare the UTC offsets
of the start and end times, using their own timezones and
the given timezone. */
- status = cal_client_get_timezone (client,
- start_datetime.tzid,
- &start_zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, start_datetime.tzid,
+ &start_zone, NULL))
goto out;
if (start_datetime.value) {
@@ -160,10 +157,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
goto out;
}
- status = cal_client_get_timezone (client,
- end_datetime.tzid,
- &end_zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, end_datetime.tzid,
+ &end_zone, NULL))
goto out;
if (end_datetime.value) {
@@ -210,8 +205,8 @@ gboolean
cal_comp_is_on_server (CalComponent *comp, CalClient *client)
{
const char *uid;
- CalClientGetStatus status;
icalcomponent *icalcomp;
+ GError *error = NULL;
g_return_val_if_fail (comp != NULL, FALSE);
g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
@@ -226,24 +221,15 @@ cal_comp_is_on_server (CalComponent *comp, CalClient *client)
*/
cal_component_get_uid (comp, &uid);
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
+ if (cal_client_get_object (client, uid, NULL, &icalcomp, &error)) {
icalcomponent_free (icalcomp);
- return TRUE;
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("confirm_delete_empty_appointment(): Syntax error when getting "
- "object `%s'",
- uid);
return TRUE;
+ }
- case CAL_CLIENT_GET_NOT_FOUND:
- return FALSE;
-
- default:
- g_assert_not_reached ();
+ if (error) {
+ g_warning ("cal_comp_is_on_server(): %s", error->message);
+ g_error_free (error);
}
return FALSE;
@@ -268,7 +254,7 @@ cal_comp_event_new_with_defaults (CalClient *client)
icalproperty *icalprop;
CalAlarmTrigger trigger;
- if (cal_client_get_default_object (client, CALOBJ_TYPE_EVENT, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (client, &icalcomp, NULL))
return NULL;
comp = cal_component_new ();
@@ -334,8 +320,16 @@ cal_comp_task_new_with_defaults (CalClient *client)
CalComponent *comp;
icalcomponent *icalcomp;
- if (cal_client_get_default_object (client, CALOBJ_TYPE_TODO, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (client, &icalcomp, NULL))
+ return NULL;
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ g_object_unref (comp);
+ icalcomponent_free (icalcomp);
+
return NULL;
+ }
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c
index 191a8d85ea..7adc5e83df 100644
--- a/calendar/gui/control-factory.c
+++ b/calendar/gui/control-factory.c
@@ -69,8 +69,11 @@ get_prop (BonoboPropertyBag *bag,
CORBA_Environment *ev,
gpointer user_data)
{
- GnomeCalendar *gcal = user_data;
+ GnomeCalendar *gcal;
const char *uri;
+ BonoboControl *control = user_data;
+
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (control);
switch (arg_id) {
@@ -96,6 +99,7 @@ get_prop (BonoboPropertyBag *bag,
case GNOME_CAL_LIST_VIEW:
BONOBO_ARG_SET_STRING (arg, "list");
break;
+ default:
}
break;
@@ -104,7 +108,6 @@ get_prop (BonoboPropertyBag *bag,
}
}
-
static void
set_prop (BonoboPropertyBag *bag,
const BonoboArg *arg,
@@ -112,14 +115,19 @@ set_prop (BonoboPropertyBag *bag,
CORBA_Environment *ev,
gpointer user_data)
{
- GnomeCalendar *gcal = user_data;
+ GnomeCalendar *gcal;
char *string;
GnomeCalendarViewType view;
+ BonoboControl *control = user_data;
+
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (control);
switch (arg_id) {
case PROPERTY_CALENDAR_URI_IDX:
string = BONOBO_ARG_GET_STRING (arg);
- if (!gnome_calendar_open (gcal, string)) {
+ if (gnome_calendar_add_event_uri (gcal, string)) {
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
+ } else {
char *msg;
msg = g_strdup_printf (_("Could not open the folder in '%s'"), string);
@@ -161,7 +169,7 @@ calendar_properties_init (GnomeCalendar *gcal, BonoboControl *control)
{
BonoboPropertyBag *pbag;
- pbag = bonobo_property_bag_new (get_prop, set_prop, gcal);
+ pbag = bonobo_property_bag_new (get_prop, set_prop, control);
bonobo_property_bag_add (pbag,
PROPERTY_CALENDAR_URI,
diff --git a/calendar/gui/control-factory.h b/calendar/gui/control-factory.h
index f599f7b3b8..bab1611c03 100644
--- a/calendar/gui/control-factory.h
+++ b/calendar/gui/control-factory.h
@@ -23,6 +23,8 @@
#ifndef _CONTROL_FACTORY_H_
#define _CONTROL_FACTORY_H_
+#include <bonobo/bonobo-control.h>
+
BonoboControl *control_factory_new_control (void);
#endif /* _CONTROL_FACTORY_H_ */
diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am
index 2466ffaa14..84424f8cc0 100644
--- a/calendar/gui/dialogs/Makefile.am
+++ b/calendar/gui/dialogs/Makefile.am
@@ -61,6 +61,8 @@ libcal_dialogs_la_SOURCES = \
event-page.h \
meeting-page.c \
meeting-page.h \
+ new-calendar.c \
+ new-calendar.h \
recurrence-page.c \
recurrence-page.h \
recur-comp.c \
@@ -85,6 +87,7 @@ glade_DATA = \
e-delegate-dialog.glade \
event-page.glade \
meeting-page.glade \
+ new-calendar.glade \
recurrence-page.glade \
schedule-page.glade \
task-details-page.glade \
diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c
index ef13b78b13..b105dc3c23 100644
--- a/calendar/gui/dialogs/alarm-options.c
+++ b/calendar/gui/dialogs/alarm-options.c
@@ -39,7 +39,7 @@
#include <bonobo/bonobo-widget.h>
#include <libgnomeui/gnome-file-entry.h>
#include <glade/glade.h>
-#include <ebook/e-destination.h>
+#include <addressbook/util/eab-destination.h>
#include "Evolution-Addressbook-SelectNames.h"
#include "e-util/e-dialog-widgets.h"
#include "alarm-options.h"
@@ -307,7 +307,7 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
CalComponentText description;
GtkTextBuffer *text_buffer;
GSList *attendee_list, *l;
- EDestination **destv;
+ EABDestination **destv;
int len, i;
/* Recipients */
@@ -315,22 +315,22 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
len = g_slist_length (attendee_list);
if (len <= 0) {
- destv = g_new0 (EDestination *, 2);
- destv[0] = e_destination_new ();
- e_destination_set_email (destv[0], dialog->email);
+ destv = g_new0 (EABDestination *, 2);
+ destv[0] = eab_destination_new ();
+ eab_destination_set_email (destv[0], dialog->email);
destv[1] = NULL;
len = 1;
} else {
- destv = g_new0 (EDestination *, len + 1);
+ destv = g_new0 (EABDestination *, len + 1);
for (l = attendee_list, i = 0; l != NULL; l = l->next, i++) {
CalComponentAttendee *a = l->data;
- EDestination *dest;
+ EABDestination *dest;
- dest = e_destination_new ();
+ dest = eab_destination_new ();
if (a->cn != NULL && *a->cn)
- e_destination_set_name (dest, a->cn);
+ eab_destination_set_name (dest, a->cn);
if (a->value != NULL && *a->value)
- e_destination_set_email (dest, a->value);
+ eab_destination_set_email (dest, a->value);
destv[i] = dest;
}
@@ -338,7 +338,7 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
}
bonobo_widget_set_property (BONOBO_WIDGET (dialog->malarm_addresses),
- "destinations", e_destination_exportv (destv), NULL);
+ "destinations", eab_destination_exportv (destv), NULL);
for (i = 0; i < len; i++)
g_object_unref (GTK_OBJECT (destv[i]));
@@ -617,7 +617,7 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
char *str;
CalComponentText description;
GSList *attendee_list = NULL;
- EDestination **destv;
+ EABDestination **destv;
GtkTextBuffer *text_buffer;
GtkTextIter text_iter_start, text_iter_end;
icalcomponent *icalcomp;
@@ -627,18 +627,18 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
/* Attendees */
bonobo_widget_get_property (BONOBO_WIDGET (dialog->malarm_addresses), "destinations",
TC_CORBA_string, &str, NULL);
- destv = e_destination_importv (str);
+ destv = eab_destination_importv (str);
g_free (str);
for (i = 0; destv[i] != NULL; i++) {
- EDestination *dest;
+ EABDestination *dest;
CalComponentAttendee *a;
dest = destv[i];
a = g_new0 (CalComponentAttendee, 1);
- a->value = e_destination_get_email (dest);
- a->cn = e_destination_get_name (dest);
+ a->value = eab_destination_get_email (dest);
+ a->cn = eab_destination_get_name (dest);
attendee_list = g_slist_append (attendee_list, a);
}
@@ -646,7 +646,7 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
cal_component_alarm_set_attendee_list (alarm, attendee_list);
cal_component_free_attendee_list (attendee_list);
- e_destination_freev (destv);
+ eab_destination_freev (destv);
/* Description */
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index 82de4e6d5a..593d342e70 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -129,7 +129,7 @@ get_dtend (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_end),
- &zone);
+ &zone, NULL);
comp_data->dtend->zone = zone;
}
@@ -308,8 +308,12 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecmc_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index 6bca52586c..76e2e140f3 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -223,7 +223,7 @@ get_completed (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_completed),
- &zone);
+ &zone, NULL);
comp_data->completed->zone = zone;
}
@@ -253,7 +253,7 @@ get_due (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_due),
- &zone);
+ &zone, NULL);
comp_data->due->zone = zone;
}
@@ -399,7 +399,7 @@ get_due_status (ECalModelTasks *model, ECalModelComponent *comp_data)
/* Get the current time in the same timezone as the DUE date.*/
status = cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (due_tt),
- &zone);
+ &zone, NULL);
if (status != CAL_CLIENT_GET_SUCCESS)
return E_CAL_MODEL_TASKS_DUE_FUTURE;
@@ -756,8 +756,12 @@ ecmt_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecmt_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 1c231f9c72..c8b706c66e 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -41,6 +41,9 @@ struct _ECalModelPrivate {
/* The list of clients we are managing. Each element is of type ECalModelClient */
GList *clients;
+ /* The default client in the list */
+ CalClient *default_client;
+
/* Array for storing the objects. Each element is of type ECalModelComponent */
GPtrArray *objects;
@@ -352,7 +355,7 @@ get_dtstart (ECalModel *model, ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_start),
- &zone);
+ &zone, NULL);
comp_data->dtstart->zone = zone;
}
@@ -609,8 +612,12 @@ ecm_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecm_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
@@ -673,7 +680,10 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row)
model_class->fill_component_from_model (model, &comp_data, source_model, row);
}
- if (cal_client_update_objects (comp_data.client, comp_data.icalcomp) != CAL_CLIENT_RESULT_SUCCESS) {
+
+ if (!cal_client_create_object (comp_data.client, comp_data.icalcomp, NULL, NULL)) {
+ g_warning (G_STRLOC ": Could not create the object!");
+
/* FIXME: show error dialog */
}
@@ -987,46 +997,53 @@ CalClient *
e_cal_model_get_default_client (ECalModel *model)
{
ECalModelPrivate *priv;
- GList *l;
- gchar *default_uri = NULL;
- EConfigListener *db;
ECalModelClient *client_data;
+ g_return_val_if_fail (model != NULL, NULL);
g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
-
+
priv = model->priv;
+ /* we always return a valid CalClient, since we rely on it in many places */
+ if (priv->default_client)
+ return priv->default_client;
+
if (!priv->clients)
return NULL;
- db = e_config_listener_new ();
+ client_data = (ECalModelClient *) priv->clients->data;
- /* look at the configuration and return the real default calendar if we've got it loaded */
- if (priv->kind == ICAL_VEVENT_COMPONENT)
- default_uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/calendar_uri");
- else if (priv->kind == ICAL_VTODO_COMPONENT)
- default_uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/tasks_uri");
+ return client_data ? client_data->client : NULL;
+}
- g_object_unref (db);
+void
+e_cal_model_set_default_client (ECalModel *model, CalClient *client)
+{
+ ECalModelPrivate *priv;
+ GList *l;
+ gboolean found = FALSE;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (client));
- if (!default_uri) {
- client_data = (ECalModelClient *) priv->clients->data;
- return client_data->client;
- }
+ priv = model->priv;
+ /* See if we already know about the client */
for (l = priv->clients; l != NULL; l = l->next) {
- client_data = (ECalModelClient *) l->data;
+ ECalModelClient *client_data = l->data;
- if (!strcmp (default_uri, cal_client_get_uri (client_data->client))) {
- g_free (default_uri);
- return client_data->client;
- }
+ if (client == client_data->client)
+ found = TRUE;
}
- g_free (default_uri);
-
- client_data = (ECalModelClient *) priv->clients->data;
- return client_data->client;
+ /* If its not found, add it */
+ if (!found)
+ e_cal_model_add_client (model, client);
+
+ /* Store the default client */
+ priv->default_client = client;
}
/**
@@ -1048,6 +1065,29 @@ e_cal_model_get_client_list (ECalModel *model)
return list;
}
+/**
+ * e_cal_model_get_client_for_uri
+ * @model: A calendar model.
+ * @uri: Uri for the client to get.
+ */
+CalClient *
+e_cal_model_get_client_for_uri (ECalModel *model, const char *uri)
+{
+ GList *l;
+
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ for (l = model->priv->clients; l != NULL; l = l->next) {
+ ECalModelClient *client_data = (ECalModelClient *) l->data;
+
+ if (!strcmp (uri, cal_client_get_uri (client_data->client)))
+ return client_data->client;
+ }
+
+ return NULL;
+}
+
static ECalModelComponent *
search_by_uid_and_client (ECalModelPrivate *priv, CalClient *client, const char *uid)
{
@@ -1084,124 +1124,119 @@ get_position_in_array (GPtrArray *objects, gpointer item)
}
static void
-query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress,
- int n_scanned, int total,
- gpointer user_data)
+query_objects_added_cb (CalQuery *query, GList *objects, gpointer user_data)
{
- ECalModelPrivate *priv;
- icalcomponent *new_icalcomp;
- CalClientGetStatus status;
- ECalModelComponent *comp_data;
- gint pos;
ECalModel *model = (ECalModel *) user_data;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
+ ECalModelPrivate *priv;
+ GList *l;
+ int start_row;
+
priv = model->priv;
e_table_model_pre_change (E_TABLE_MODEL (model));
- comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), uid);
- status = cal_client_get_object (cal_query_get_client (query), uid, &new_icalcomp);
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS :
- if (comp_data) {
- if (comp_data->icalcomp)
- icalcomponent_free (comp_data->icalcomp);
- if (comp_data->dtstart) {
- g_free (comp_data->dtstart);
- comp_data->dtstart = NULL;
- }
- if (comp_data->dtend) {
- g_free (comp_data->dtend);
- comp_data->dtend = NULL;
- }
- if (comp_data->due) {
- g_free (comp_data->due);
- comp_data->due = NULL;
- }
- if (comp_data->completed) {
- g_free (comp_data->completed);
- comp_data->completed = NULL;
- }
+ start_row = priv->objects->len ? priv->objects->len - 1 : 0;
+
+ for (l = objects; l; l = l->next) {
+ ECalModelComponent *comp_data;
- comp_data->icalcomp = new_icalcomp;
+ comp_data = g_new0 (ECalModelComponent, 1);
+ comp_data->client = cal_query_get_client (query);
+ comp_data->icalcomp = icalcomponent_new_clone (l->data);
- e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
- } else {
- comp_data = g_new0 (ECalModelComponent, 1);
- comp_data->client = cal_query_get_client (query);
- comp_data->icalcomp = new_icalcomp;
+ g_ptr_array_add (priv->objects, comp_data);
+ }
- g_ptr_array_add (priv->objects, comp_data);
- e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1);
- }
- break;
- case CAL_CLIENT_GET_NOT_FOUND :
- case CAL_CLIENT_GET_SYNTAX_ERROR :
- if (comp_data) {
- /* Nothing; the object may have been removed from the server. We just
- notify that the old object was deleted.
- */
- pos = get_position_in_array (priv->objects, comp_data);
+ e_table_model_rows_inserted (E_TABLE_MODEL (model), start_row, priv->objects->len - start_row);
+}
- g_ptr_array_remove (priv->objects, comp_data);
- free_comp_data (comp_data);
+static void
+query_objects_modified_cb (CalQuery *query, GList *objects, gpointer user_data)
+{
+ ECalModelPrivate *priv;
+ ECalModel *model = (ECalModel *) user_data;
+ GList *l;
+
+ priv = model->priv;
- e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
- } else
- e_table_model_no_change (E_TABLE_MODEL (model));
- break;
- default :
- g_assert_not_reached ();
+ for (l = objects; l; l = l->next) {
+ ECalModelComponent *comp_data;
+
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+
+ comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), icalcomponent_get_uid (l->data));
+ g_assert (comp_data);
+
+ if (comp_data->icalcomp)
+ icalcomponent_free (comp_data->icalcomp);
+ if (comp_data->dtstart) {
+ g_free (comp_data->dtstart);
+ comp_data->dtstart = NULL;
+ }
+ if (comp_data->dtend) {
+ g_free (comp_data->dtend);
+ comp_data->dtend = NULL;
+ }
+ if (comp_data->due) {
+ g_free (comp_data->due);
+ comp_data->due = NULL;
+ }
+ if (comp_data->completed) {
+ g_free (comp_data->completed);
+ comp_data->completed = NULL;
+ }
+
+ comp_data->icalcomp = icalcomponent_new_clone (l->data);
+
+ e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
}
}
static void
-query_obj_removed_cb (CalQuery *query, const char *uid, gpointer user_data)
+query_objects_removed_cb (CalQuery *query, GList *uids, gpointer user_data)
{
- ECalModelComponent *comp_data;
ECalModelPrivate *priv;
ECalModel *model = (ECalModel *) user_data;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
+ GList *l;
+
priv = model->priv;
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), uid);
- if (comp_data) {
- gint pos = get_position_in_array (priv->objects, comp_data);
+ for (l = uids; l; l = l->next) {
+ ECalModelComponent *comp_data;
+ int pos;
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+
+ comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), l->data);
+ g_assert (comp_data);
+
+ pos = get_position_in_array (priv->objects, comp_data);
+
g_ptr_array_remove (priv->objects, comp_data);
free_comp_data (comp_data);
-
+
e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
- } else
- e_table_model_no_change (E_TABLE_MODEL (model));
+ }
}
static void
-query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer user_data)
+query_progress_cb (CalQuery *query, const char *message, int percent, gpointer user_data)
{
ECalModel *model = (ECalModel *) user_data;
g_return_if_fail (E_IS_CAL_MODEL (model));
- if (status != CAL_QUERY_DONE_SUCCESS)
- g_warning ("query done: %s\n", error_str);
+ /* FIXME Update status bar */
}
static void
-query_eval_error_cb (CalQuery *query, const char *error_str, gpointer user_data)
+query_done_cb (CalQuery *query, ECalendarStatus status, gpointer user_data)
{
- ECalModel *model = (ECalModel *) user_data;
+ ECalModel *model = (ECalModel *) user_data;
g_return_if_fail (E_IS_CAL_MODEL (model));
- g_warning ("eval error: %s\n", error_str);
+ /* FIXME Clear status bar */
}
/* Builds a complete query sexp for the calendar model by adding the predicates
@@ -1248,24 +1283,28 @@ update_query_for_client (ECalModel *model, ECalModelClient *client_data)
g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, model);
g_object_unref (client_data->query);
+ client_data->query = NULL;
}
/* prepare the query */
g_assert (priv->sexp != NULL);
real_sexp = adjust_query_sexp (model, priv->sexp);
- client_data->query = cal_client_get_query (client_data->client, real_sexp);
- g_free (real_sexp);
+ if (!cal_client_get_query (client_data->client, real_sexp, &client_data->query, NULL)) {
+ g_warning (G_STRLOC ": Unable to get query");
+ g_free (real_sexp);
- if (!client_data->query) {
- g_message ("update_query_for_client(): Could not create the query");
return;
- }
+ }
+ g_free (real_sexp);
- g_signal_connect (client_data->query, "obj_updated", G_CALLBACK (query_obj_updated_cb), model);
- g_signal_connect (client_data->query, "obj_removed", G_CALLBACK (query_obj_removed_cb), model);
+ g_signal_connect (client_data->query, "objects_added", G_CALLBACK (query_objects_added_cb), model);
+ g_signal_connect (client_data->query, "objects_modified", G_CALLBACK (query_objects_modified_cb), model);
+ g_signal_connect (client_data->query, "objects_removed", G_CALLBACK (query_objects_removed_cb), model);
+ g_signal_connect (client_data->query, "query_progress", G_CALLBACK (query_progress_cb), model);
g_signal_connect (client_data->query, "query_done", G_CALLBACK (query_done_cb), model);
- g_signal_connect (client_data->query, "eval_error", G_CALLBACK (query_eval_error_cb), model);
+
+ cal_query_start (client_data->query);
}
static void
@@ -1465,9 +1504,22 @@ e_cal_model_create_component_with_defaults (ECalModel *model)
return NULL;
}
+ if (!comp)
+ return icalcomponent_new (priv->kind);
+
icalcomp = icalcomponent_new_clone (cal_component_get_icalcomponent (comp));
g_object_unref (comp);
+ /* make sure the component has an UID */
+ if (!icalcomponent_get_uid (icalcomp)) {
+ char *uid;
+
+ uid = cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+
+ g_free (uid);
+ }
+
return icalcomp;
}
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index ec8ab36c44..9c673ca439 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -88,7 +88,9 @@ void e_cal_model_set_default_category (ECalModel *model, const gc
void e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24);
CalClient *e_cal_model_get_default_client (ECalModel *model);
+void e_cal_model_set_default_client (ECalModel *model, CalClient *client);
GList *e_cal_model_get_client_list (ECalModel *model);
+CalClient *e_cal_model_get_client_for_uri (ECalModel *model, const char *uri);
void e_cal_model_add_client (ECalModel *model, CalClient *client);
void e_cal_model_remove_client (ECalModel *model, CalClient *client);
void e_cal_model_remove_all_clients (ECalModel *model);
diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c
index 381dca2542..869c8001a3 100644
--- a/calendar/gui/e-cal-view.c
+++ b/calendar/gui/e-cal-view.c
@@ -37,9 +37,11 @@
#include "comp-util.h"
#include "e-cal-model-calendar.h"
#include "e-cal-view.h"
+#include "e-comp-editor-registry.h"
#include "itip-utils.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
+#include "dialogs/event-editor.h"
#include "dialogs/send-comp.h"
#include "dialogs/cancel-comp.h"
#include "dialogs/recur-comp.h"
@@ -70,15 +72,28 @@ struct _ECalViewPrivate {
/* The timezone. */
icaltimezone *zone;
+
+ /* The default category */
+ char *default_category;
};
static void e_cal_view_class_init (ECalViewClass *klass);
static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass);
+static void e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void e_cal_view_destroy (GtkObject *object);
static GObjectClass *parent_class = NULL;
static GdkAtom clipboard_atom = GDK_NONE;
+extern ECompEditorRegistry *comp_editor_registry;
+
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_MODEL,
+};
+/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
/* Signal IDs */
enum {
SELECTION_CHANGED,
@@ -91,12 +106,71 @@ enum {
static guint e_cal_view_signals[LAST_SIGNAL] = { 0 };
static void
+e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ e_cal_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, e_cal_view_get_model (cal_view));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
e_cal_view_class_init (ECalViewClass *klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ /* Method override */
+ gobject_class->set_property = e_cal_view_set_property;
+ gobject_class->get_property = e_cal_view_get_property;
+ object_class->destroy = e_cal_view_destroy;
+
+ klass->selection_changed = NULL;
+ klass->event_changed = NULL;
+ klass->event_added = NULL;
+
+ klass->get_selected_events = NULL;
+ klass->get_selected_time_range = NULL;
+ klass->set_selected_time_range = NULL;
+ klass->get_visible_time_range = NULL;
+ klass->update_query = NULL;
+
+ g_object_class_install_property (gobject_class, PROP_MODEL,
+ g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT));
+
/* Create class' signals */
e_cal_view_signals[SELECTION_CHANGED] =
g_signal_new ("selection_changed",
@@ -135,19 +209,6 @@ e_cal_view_class_init (ECalViewClass *klass)
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- /* Method override */
- object_class->destroy = e_cal_view_destroy;
-
- klass->selection_changed = NULL;
- klass->event_changed = NULL;
- klass->event_added = NULL;
-
- klass->get_selected_events = NULL;
- klass->get_selected_time_range = NULL;
- klass->set_selected_time_range = NULL;
- klass->get_visible_time_range = NULL;
- klass->update_query = NULL;
-
/* clipboard atom */
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -208,6 +269,45 @@ selection_clear_event (GtkWidget *invisible,
}
static void
+selection_received_add_event (ECalView *cal_view, CalClient *client, time_t selected_time_start,
+ icaltimezone *default_zone, icalcomponent *icalcomp)
+{
+ CalComponent *comp;
+ struct icaltimetype itime;
+ time_t tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ char *uid;
+
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (icalcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (icalcomp, itime);
+
+ /* FIXME The new uid stuff can go away once we actually set it in the backend */
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+}
+
+static void
selection_received (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint time,
@@ -216,12 +316,7 @@ selection_received (GtkWidget *invisible,
char *comp_str, *default_tzid;
icalcomponent *icalcomp;
icalcomponent_kind kind;
- CalComponent *comp;
time_t selected_time_start, selected_time_end;
- struct icaltimetype itime;
- time_t tt_start, tt_end;
- struct icaldurationtype ic_dur;
- char *uid;
icaltimezone *default_zone;
CalClient *client;
@@ -238,21 +333,21 @@ selection_received (GtkWidget *invisible,
return;
default_tzid = calendar_config_get_timezone ();
+
client = e_cal_model_get_default_client (cal_view->priv->model);
- cal_client_get_timezone (client, default_tzid, &default_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, default_tzid, &default_zone, NULL);
/* check the type of the component */
+ /* FIXME An error dialog if we return? */
kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
return;
- }
e_cal_view_set_status_message (cal_view, _("Updating objects"));
e_cal_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+ /* FIXME Timezone handling */
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
icalcomponent *subcomp;
@@ -260,69 +355,27 @@ selection_received (GtkWidget *invisible,
subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
while (subcomp) {
child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start,
- FALSE, default_zone);
-
- icalcomponent_set_dtstart (subcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (subcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (subcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ if (child_kind == ICAL_VEVENT_COMPONENT)
+ selection_received_add_event (cal_view, client, selected_time_start,
+ default_zone, subcomp);
+ else if (child_kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ cal_client_add_timezone (client, zone, NULL);
+
+ icaltimezone_free (zone, 1);
}
+
subcomp = icalcomponent_get_next_component (
icalcomp, ICAL_ANY_COMPONENT);
}
icalcomponent_free (icalcomp);
- }
- else {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
-
- icalcomponent_set_dtstart (icalcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (icalcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (icalcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ } else {
+ selection_received_add_event (cal_view, client, selected_time_start, default_zone, icalcomp);
}
e_cal_view_set_status_message (cal_view, NULL);
@@ -334,6 +387,14 @@ e_cal_view_init (ECalView *cal_view, ECalViewClass *klass)
cal_view->priv = g_new0 (ECalViewPrivate, 1);
cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new ();
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed",
+ G_CALLBACK (model_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed",
+ G_CALLBACK (model_row_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
/* Set up the invisible widget for the clipboard selections */
cal_view->priv->invisible = gtk_invisible_new ();
@@ -380,6 +441,11 @@ e_cal_view_destroy (GtkObject *object)
cal_view->priv->clipboard_selection = NULL;
}
+ if (cal_view->priv->default_category) {
+ g_free (cal_view->priv->default_category);
+ cal_view->priv->default_category = NULL;
+ }
+
g_free (cal_view->priv);
cal_view->priv = NULL;
}
@@ -460,11 +526,35 @@ e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone)
old_zone, cal_view->priv->zone);
}
+const char *
+e_cal_view_get_default_category (ECalView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
+ return (const char *) cal_view->priv->default_category;
+}
+
+/**
+ * e_cal_view_set_default_category
+ * @cal_view: A calendar view.
+ * @category: Default category name or NULL for no category.
+ *
+ * Sets the default category that will be used when creating new calendar
+ * components from the given calendar view.
+ */
void
-e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+e_cal_view_set_default_category (ECalView *cal_view, const char *category)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ if (cal_view->priv->default_category)
+ g_free (cal_view->priv->default_category);
+
+ cal_view->priv->default_category = g_strdup (category);
+}
+void
+e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+{
g_return_if_fail (E_IS_CAL_VIEW (cal_view));
if (!message || !*message) {
@@ -473,14 +563,19 @@ e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
cal_view->priv->activity = NULL;
}
} else if (!cal_view->priv->activity) {
+#if 0
int display;
+#endif
char *client_id = g_strdup_printf ("%p", cal_view);
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL);
+
+#if 0
cal_view->priv->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
@@ -564,9 +659,9 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
e_cal_view_copy_clipboard (cal_view);
for (l = selected; l != NULL; l = l->next) {
CalComponent *comp;
-
ECalViewEvent *event = (ECalViewEvent *) l->data;
-
+ GError *error = NULL;
+
if (!event)
continue;
@@ -580,9 +675,11 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
event->comp_data->client, NULL);
cal_component_get_uid (comp, &uid);
- delete_error_dialog (cal_client_remove_object (event->comp_data->client, uid),
- CAL_COMPONENT_EVENT);
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
+
g_object_unref (comp);
}
@@ -657,7 +754,8 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) {
const char *uid;
-
+ GError *error = NULL;
+
if (itip_organizer_is_user (comp, event->comp_data->client)
&& cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
event->comp_data->client,
@@ -670,9 +768,10 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
g_object_unref (comp);
return;
}
-
- delete_error_dialog (
- cal_client_remove_object (event->comp_data->client, uid), CAL_COMPONENT_EVENT);
+
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
}
g_object_unref (comp);
@@ -719,35 +818,21 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
{
ECalViewEvent *event;
GList *selected;
-
+ const char *uid;
+ GError *error = NULL;
+
selected = e_cal_view_get_selected_events (cal_view);
if (!selected)
return;
event = (ECalViewEvent *) selected->data;
- if (cal_util_component_is_instance (event->comp_data->icalcomp)) {
- const char *uid;
-
- uid = icalcomponent_get_uid (event->comp_data->icalcomp);
- delete_error_dialog (
- cal_client_remove_object_with_mod (event->comp_data->client, uid, CALOBJ_MOD_THIS),
- CAL_COMPONENT_EVENT);
- } else {
- CalComponent *comp;
+ uid = icalcomponent_get_uid (event->comp_data->icalcomp);
+ /* FIXME: use 'rid' argument */
+ cal_client_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error);
- /* we must duplicate the CalComponent, or we won't know it has changed
- when we get the "update_event" signal */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, cal_view->priv->zone);
-
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_cal_view_delete_selected_occurrence(): Could not update the object!");
-
- g_object_unref (comp);
- }
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
/* free memory */
g_list_free (selected);
@@ -756,11 +841,9 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
static void
on_new_appointment (GtkWidget *widget, gpointer user_data)
{
- time_t dtstart, dtend;
ECalView *cal_view = (ECalView *) user_data;
- e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, FALSE);
+ e_cal_view_new_appointment (cal_view);
}
static void
@@ -770,7 +853,7 @@ on_new_event (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, TRUE, FALSE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
}
static void
@@ -780,7 +863,7 @@ on_new_meeting (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, TRUE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
}
static void
@@ -817,8 +900,8 @@ on_edit_appointment (GtkWidget *widget, gpointer user_data)
ECalViewEvent *event = (ECalViewEvent *) selected->data;
if (event)
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client,
- event->comp_data->icalcomp, FALSE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
g_list_free (selected);
}
@@ -834,7 +917,7 @@ on_print (GtkWidget *widget, gpointer user_data)
cal_view = E_CAL_VIEW (user_data);
- gnome_calendar_get_current_time_range (cal_view->priv->calendar, &start, NULL);
+ e_cal_view_get_visible_time_range (cal_view, &start, NULL);
view_type = gnome_calendar_get_view (cal_view->priv->calendar);
switch (view_type) {
@@ -930,7 +1013,7 @@ on_meeting (GtkWidget *widget, gpointer user_data)
selected = e_cal_view_get_selected_events (cal_view);
if (selected) {
ECalViewEvent *event = (ECalViewEvent *) selected->data;
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client, event->comp_data->icalcomp, TRUE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE);
g_list_free (selected);
}
@@ -962,7 +1045,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
ECalView *cal_view;
icaltimezone *utc;
time_t start = time (NULL), end;
- GList *comp_list, *client_list, *cl;
+ GList *comp_list = NULL, *client_list, *cl;
cal_view = E_CAL_VIEW (user_data);
@@ -972,8 +1055,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
client_list = e_cal_model_get_client_list (cal_view->priv->model);
for (cl = client_list; cl != NULL; cl = cl->next) {
- comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -1041,14 +1123,6 @@ on_paste (GtkWidget *widget, gpointer user_data)
e_cal_view_paste_clipboard (cal_view);
}
-static void
-on_unrecur_appointment (GtkWidget *widget, gpointer user_data)
-{
- ECalView *cal_view = E_CAL_VIEW (user_data);
-
- gnome_calendar_unrecur_selection (cal_view->priv->calendar);
-}
-
enum {
/*
* This is used to "flag" events that can not be editted
@@ -1142,7 +1216,6 @@ static EPopupMenu child_items [] = {
E_POPUP_SEPARATOR,
E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING),
- E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE | MASK_INSTANCE),
E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
@@ -1209,21 +1282,18 @@ setup_popup_icons (EPopupMenu *context_menu)
GtkMenu *
e_cal_view_create_popup_menu (ECalView *cal_view)
{
- gboolean being_edited, have_selection;
GList *selected;
EPopupMenu *context_menu;
guint32 disable_mask = 0, hide_mask = 0;
GtkMenu *popup;
CalClient *client = NULL;
-
+ gboolean read_only = TRUE;
+
g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
/* get the selection */
- being_edited = FALSE;
selected = e_cal_view_get_selected_events (cal_view);
- have_selection = GTK_WIDGET_HAS_FOCUS (cal_view) && selected != NULL;
-
if (selected == NULL) {
cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar);
main_items[9].submenu = cal_view->priv->view_menu;
@@ -1260,15 +1330,158 @@ e_cal_view_create_popup_menu (ECalView *cal_view)
client = event->comp_data->client;
}
- if (cal_client_is_read_only (client))
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (read_only)
disable_mask |= MASK_EDITABLE;
- if (being_edited)
- disable_mask |= MASK_EDITING;
-
setup_popup_icons (context_menu);
popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view);
g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view);
return popup;
}
+
+/**
+ * e_cal_view_new_appointment_for
+ * @cal_view: A calendar view.
+ * @dtstart: A Unix time_t that marks the beginning of the appointment.
+ * @dtend: A Unix time_t that marks the end of the appointment.
+ * @all_day: If TRUE, the dtstart and dtend are expanded to cover
+ * the entire day, and the event is set to TRANSPARENT.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an event editor dialog for a new appointment.
+ */
+void
+e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart, time_t dtend,
+ gboolean all_day,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ struct icaltimetype itt;
+ CalComponentDateTime dt;
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ CalComponentTransparency transparency;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ priv = cal_view->priv;
+
+ dt.value = &itt;
+ if (all_day)
+ dt.tzid = NULL;
+ else
+ dt.tzid = icaltimezone_get_tzid (priv->zone);
+
+ icalcomp = e_cal_model_create_component_with_defaults (priv->model);
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* DTSTART, DTEND */
+ itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
+ if (all_day) {
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtstart (comp, &dt);
+
+ itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
+ if (all_day) {
+ /* We round it up to the end of the day, unless it is
+ already set to midnight */
+ if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
+ icaltime_adjust (&itt, 1, 0, 0, 0);
+ }
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtend (comp, &dt);
+
+ /* TRANSPARENCY */
+ transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
+ : CAL_COMPONENT_TRANSP_OPAQUE;
+ cal_component_set_transparency (comp, transparency);
+
+ /* CATEGORY */
+ cal_component_set_categories (comp, priv->default_category);
+
+ /* edit the object */
+ cal_component_commit_sequence (comp);
+
+ e_cal_view_edit_appointment (cal_view,
+ e_cal_model_get_default_client (priv->model),
+ icalcomp, meeting);
+
+ g_object_unref (comp);
+}
+
+/**
+ * e_cal_view_new_appointment
+ * @cal_view: A calendar view.
+ *
+ * Opens an event editor dialog for a new appointment. The appointment's
+ * start and end times are set to the currently selected time range in
+ * the calendar view.
+ */
+void
+e_cal_view_new_appointment (ECalView *cal_view)
+{
+ time_t dtstart, dtend;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+/**
+ * e_cal_view_edit_appointment
+ * @cal_view: A calendar view.
+ * @client: Calendar client.
+ * @icalcomp: The object to be edited.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an editor window to allow the user to edit the selected
+ * object.
+ */
+void
+e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ CompEditor *ce;
+ const char *uid;
+ CalComponent *comp;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+ g_return_if_fail (IS_CAL_CLIENT (client));
+ g_return_if_fail (icalcomp != NULL);
+
+ priv = cal_view->priv;
+
+ uid = icalcomponent_get_uid (icalcomp);
+
+ ce = e_comp_editor_registry_find (comp_editor_registry, uid);
+ if (!ce) {
+ EventEditor *ee;
+
+ ee = event_editor_new (client);
+ ce = COMP_EDITOR (ee);
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ comp_editor_edit_comp (ce, comp);
+ if (meeting)
+ event_editor_show_meeting (ee);
+
+ e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
+
+ g_object_unref (comp);
+ }
+
+ comp_editor_focus (ce);
+}
diff --git a/calendar/gui/e-cal-view.h b/calendar/gui/e-cal-view.h
index ea7c11a00d..9a09a5236a 100644
--- a/calendar/gui/e-cal-view.h
+++ b/calendar/gui/e-cal-view.h
@@ -96,6 +96,8 @@ ECalModel *e_cal_view_get_model (ECalView *cal_view);
void e_cal_view_set_model (ECalView *cal_view, ECalModel *model);
icaltimezone *e_cal_view_get_timezone (ECalView *cal_view);
void e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone);
+const char *e_cal_view_get_default_category (ECalView *cal_view);
+void e_cal_view_set_default_category (ECalView *cal_view, const char *category);
void e_cal_view_set_status_message (ECalView *cal_view, const gchar *message);
@@ -114,6 +116,17 @@ void e_cal_view_delete_selected_occurrence (ECalView *cal_view);
GtkMenu *e_cal_view_create_popup_menu (ECalView *cal_view);
+void e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart,
+ time_t dtend,
+ gboolean all_day,
+ gboolean meeting);
+void e_cal_view_new_appointment (ECalView *cal_view);
+void e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting);
+
G_END_DECLS
#endif
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 5b3f98f373..fdea4d33bb 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -725,10 +725,12 @@ delete_selected_components (ECalendarTable *cal_table)
for (l = objs; l; l = l->next) {
ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
-
- delete_error_dialog (cal_client_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp)),
- CAL_COMPONENT_TODO);
+ GError *error = NULL;
+
+ cal_client_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, CAL_COMPONENT_TODO);
+ g_clear_error (&error);
}
e_calendar_table_set_status_message (cal_table, NULL);
@@ -1052,7 +1054,8 @@ e_calendar_table_show_popup_menu (ETable *table,
GtkMenu *gtk_menu;
icalproperty *prop;
ECalModelComponent *comp_data;
-
+ gboolean read_only = TRUE;
+
n_selected = e_table_selected_count (table);
if (n_selected <= 0)
return TRUE;
@@ -1071,7 +1074,8 @@ e_calendar_table_show_popup_menu (ETable *table,
} else
hide_mask = MASK_SINGLE;
- if (cal_client_is_read_only (comp_data->client))
+ cal_client_is_read_only (comp_data->client, &read_only, NULL);
+ if (!read_only)
disable_mask |= MASK_EDITABLE;
if (cal_client_get_static_capability (comp_data->client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT))
@@ -1315,6 +1319,7 @@ selection_received (GtkWidget *invisible,
icalcomponent *icalcomp;
char *uid;
CalComponent *comp;
+ CalClient *client;
icalcomponent_kind kind;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
@@ -1338,6 +1343,8 @@ selection_received (GtkWidget *invisible,
return;
}
+ client = e_cal_model_get_default_client (cal_table->model);
+
e_calendar_table_set_status_message (cal_table, _("Updating objects"));
if (kind == ICAL_VCALENDAR_COMPONENT) {
@@ -1360,11 +1367,12 @@ selection_received (GtkWidget *invisible,
cal_component_set_icalcomponent (
tmp_comp, icalcomponent_new_clone (subcomp));
cal_component_set_uid (tmp_comp, uid);
-
- cal_client_update_object (
- e_cal_model_get_default_client (cal_table->model),
- tmp_comp);
free (uid);
+
+ /* FIXME should we convert start/due/complete times? */
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
+
g_object_unref (tmp_comp);
}
subcomp = icalcomponent_get_next_component (
@@ -1378,9 +1386,8 @@ selection_received (GtkWidget *invisible,
cal_component_set_uid (comp, (const char *) uid);
free (uid);
- cal_client_update_object (
- e_cal_model_get_default_client (cal_table->model),
- comp);
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+
g_object_unref (comp);
}
@@ -1433,8 +1440,6 @@ static GdkPixbuf *progress_icon[2] = { NULL, NULL };
void
e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *message)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
-
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
if (!message || !*message) {
@@ -1448,9 +1453,12 @@ e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *mes
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_TASKS_PROGRESS_IMAGE, NULL);
+
+#if 0 /* EPFIXME */
cal_table->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index 381dca2542..869c8001a3 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -37,9 +37,11 @@
#include "comp-util.h"
#include "e-cal-model-calendar.h"
#include "e-cal-view.h"
+#include "e-comp-editor-registry.h"
#include "itip-utils.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
+#include "dialogs/event-editor.h"
#include "dialogs/send-comp.h"
#include "dialogs/cancel-comp.h"
#include "dialogs/recur-comp.h"
@@ -70,15 +72,28 @@ struct _ECalViewPrivate {
/* The timezone. */
icaltimezone *zone;
+
+ /* The default category */
+ char *default_category;
};
static void e_cal_view_class_init (ECalViewClass *klass);
static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass);
+static void e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void e_cal_view_destroy (GtkObject *object);
static GObjectClass *parent_class = NULL;
static GdkAtom clipboard_atom = GDK_NONE;
+extern ECompEditorRegistry *comp_editor_registry;
+
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_MODEL,
+};
+/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
/* Signal IDs */
enum {
SELECTION_CHANGED,
@@ -91,12 +106,71 @@ enum {
static guint e_cal_view_signals[LAST_SIGNAL] = { 0 };
static void
+e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ e_cal_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, e_cal_view_get_model (cal_view));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
e_cal_view_class_init (ECalViewClass *klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ /* Method override */
+ gobject_class->set_property = e_cal_view_set_property;
+ gobject_class->get_property = e_cal_view_get_property;
+ object_class->destroy = e_cal_view_destroy;
+
+ klass->selection_changed = NULL;
+ klass->event_changed = NULL;
+ klass->event_added = NULL;
+
+ klass->get_selected_events = NULL;
+ klass->get_selected_time_range = NULL;
+ klass->set_selected_time_range = NULL;
+ klass->get_visible_time_range = NULL;
+ klass->update_query = NULL;
+
+ g_object_class_install_property (gobject_class, PROP_MODEL,
+ g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT));
+
/* Create class' signals */
e_cal_view_signals[SELECTION_CHANGED] =
g_signal_new ("selection_changed",
@@ -135,19 +209,6 @@ e_cal_view_class_init (ECalViewClass *klass)
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- /* Method override */
- object_class->destroy = e_cal_view_destroy;
-
- klass->selection_changed = NULL;
- klass->event_changed = NULL;
- klass->event_added = NULL;
-
- klass->get_selected_events = NULL;
- klass->get_selected_time_range = NULL;
- klass->set_selected_time_range = NULL;
- klass->get_visible_time_range = NULL;
- klass->update_query = NULL;
-
/* clipboard atom */
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -208,6 +269,45 @@ selection_clear_event (GtkWidget *invisible,
}
static void
+selection_received_add_event (ECalView *cal_view, CalClient *client, time_t selected_time_start,
+ icaltimezone *default_zone, icalcomponent *icalcomp)
+{
+ CalComponent *comp;
+ struct icaltimetype itime;
+ time_t tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ char *uid;
+
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (icalcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (icalcomp, itime);
+
+ /* FIXME The new uid stuff can go away once we actually set it in the backend */
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+}
+
+static void
selection_received (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint time,
@@ -216,12 +316,7 @@ selection_received (GtkWidget *invisible,
char *comp_str, *default_tzid;
icalcomponent *icalcomp;
icalcomponent_kind kind;
- CalComponent *comp;
time_t selected_time_start, selected_time_end;
- struct icaltimetype itime;
- time_t tt_start, tt_end;
- struct icaldurationtype ic_dur;
- char *uid;
icaltimezone *default_zone;
CalClient *client;
@@ -238,21 +333,21 @@ selection_received (GtkWidget *invisible,
return;
default_tzid = calendar_config_get_timezone ();
+
client = e_cal_model_get_default_client (cal_view->priv->model);
- cal_client_get_timezone (client, default_tzid, &default_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, default_tzid, &default_zone, NULL);
/* check the type of the component */
+ /* FIXME An error dialog if we return? */
kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
return;
- }
e_cal_view_set_status_message (cal_view, _("Updating objects"));
e_cal_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+ /* FIXME Timezone handling */
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
icalcomponent *subcomp;
@@ -260,69 +355,27 @@ selection_received (GtkWidget *invisible,
subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
while (subcomp) {
child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start,
- FALSE, default_zone);
-
- icalcomponent_set_dtstart (subcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (subcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (subcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ if (child_kind == ICAL_VEVENT_COMPONENT)
+ selection_received_add_event (cal_view, client, selected_time_start,
+ default_zone, subcomp);
+ else if (child_kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ cal_client_add_timezone (client, zone, NULL);
+
+ icaltimezone_free (zone, 1);
}
+
subcomp = icalcomponent_get_next_component (
icalcomp, ICAL_ANY_COMPONENT);
}
icalcomponent_free (icalcomp);
- }
- else {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
-
- icalcomponent_set_dtstart (icalcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (icalcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (icalcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ } else {
+ selection_received_add_event (cal_view, client, selected_time_start, default_zone, icalcomp);
}
e_cal_view_set_status_message (cal_view, NULL);
@@ -334,6 +387,14 @@ e_cal_view_init (ECalView *cal_view, ECalViewClass *klass)
cal_view->priv = g_new0 (ECalViewPrivate, 1);
cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new ();
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed",
+ G_CALLBACK (model_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed",
+ G_CALLBACK (model_row_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
/* Set up the invisible widget for the clipboard selections */
cal_view->priv->invisible = gtk_invisible_new ();
@@ -380,6 +441,11 @@ e_cal_view_destroy (GtkObject *object)
cal_view->priv->clipboard_selection = NULL;
}
+ if (cal_view->priv->default_category) {
+ g_free (cal_view->priv->default_category);
+ cal_view->priv->default_category = NULL;
+ }
+
g_free (cal_view->priv);
cal_view->priv = NULL;
}
@@ -460,11 +526,35 @@ e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone)
old_zone, cal_view->priv->zone);
}
+const char *
+e_cal_view_get_default_category (ECalView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
+ return (const char *) cal_view->priv->default_category;
+}
+
+/**
+ * e_cal_view_set_default_category
+ * @cal_view: A calendar view.
+ * @category: Default category name or NULL for no category.
+ *
+ * Sets the default category that will be used when creating new calendar
+ * components from the given calendar view.
+ */
void
-e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+e_cal_view_set_default_category (ECalView *cal_view, const char *category)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ if (cal_view->priv->default_category)
+ g_free (cal_view->priv->default_category);
+
+ cal_view->priv->default_category = g_strdup (category);
+}
+void
+e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+{
g_return_if_fail (E_IS_CAL_VIEW (cal_view));
if (!message || !*message) {
@@ -473,14 +563,19 @@ e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
cal_view->priv->activity = NULL;
}
} else if (!cal_view->priv->activity) {
+#if 0
int display;
+#endif
char *client_id = g_strdup_printf ("%p", cal_view);
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL);
+
+#if 0
cal_view->priv->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
@@ -564,9 +659,9 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
e_cal_view_copy_clipboard (cal_view);
for (l = selected; l != NULL; l = l->next) {
CalComponent *comp;
-
ECalViewEvent *event = (ECalViewEvent *) l->data;
-
+ GError *error = NULL;
+
if (!event)
continue;
@@ -580,9 +675,11 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
event->comp_data->client, NULL);
cal_component_get_uid (comp, &uid);
- delete_error_dialog (cal_client_remove_object (event->comp_data->client, uid),
- CAL_COMPONENT_EVENT);
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
+
g_object_unref (comp);
}
@@ -657,7 +754,8 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) {
const char *uid;
-
+ GError *error = NULL;
+
if (itip_organizer_is_user (comp, event->comp_data->client)
&& cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
event->comp_data->client,
@@ -670,9 +768,10 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
g_object_unref (comp);
return;
}
-
- delete_error_dialog (
- cal_client_remove_object (event->comp_data->client, uid), CAL_COMPONENT_EVENT);
+
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
}
g_object_unref (comp);
@@ -719,35 +818,21 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
{
ECalViewEvent *event;
GList *selected;
-
+ const char *uid;
+ GError *error = NULL;
+
selected = e_cal_view_get_selected_events (cal_view);
if (!selected)
return;
event = (ECalViewEvent *) selected->data;
- if (cal_util_component_is_instance (event->comp_data->icalcomp)) {
- const char *uid;
-
- uid = icalcomponent_get_uid (event->comp_data->icalcomp);
- delete_error_dialog (
- cal_client_remove_object_with_mod (event->comp_data->client, uid, CALOBJ_MOD_THIS),
- CAL_COMPONENT_EVENT);
- } else {
- CalComponent *comp;
+ uid = icalcomponent_get_uid (event->comp_data->icalcomp);
+ /* FIXME: use 'rid' argument */
+ cal_client_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error);
- /* we must duplicate the CalComponent, or we won't know it has changed
- when we get the "update_event" signal */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, cal_view->priv->zone);
-
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_cal_view_delete_selected_occurrence(): Could not update the object!");
-
- g_object_unref (comp);
- }
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
/* free memory */
g_list_free (selected);
@@ -756,11 +841,9 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
static void
on_new_appointment (GtkWidget *widget, gpointer user_data)
{
- time_t dtstart, dtend;
ECalView *cal_view = (ECalView *) user_data;
- e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, FALSE);
+ e_cal_view_new_appointment (cal_view);
}
static void
@@ -770,7 +853,7 @@ on_new_event (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, TRUE, FALSE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
}
static void
@@ -780,7 +863,7 @@ on_new_meeting (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, TRUE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
}
static void
@@ -817,8 +900,8 @@ on_edit_appointment (GtkWidget *widget, gpointer user_data)
ECalViewEvent *event = (ECalViewEvent *) selected->data;
if (event)
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client,
- event->comp_data->icalcomp, FALSE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
g_list_free (selected);
}
@@ -834,7 +917,7 @@ on_print (GtkWidget *widget, gpointer user_data)
cal_view = E_CAL_VIEW (user_data);
- gnome_calendar_get_current_time_range (cal_view->priv->calendar, &start, NULL);
+ e_cal_view_get_visible_time_range (cal_view, &start, NULL);
view_type = gnome_calendar_get_view (cal_view->priv->calendar);
switch (view_type) {
@@ -930,7 +1013,7 @@ on_meeting (GtkWidget *widget, gpointer user_data)
selected = e_cal_view_get_selected_events (cal_view);
if (selected) {
ECalViewEvent *event = (ECalViewEvent *) selected->data;
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client, event->comp_data->icalcomp, TRUE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE);
g_list_free (selected);
}
@@ -962,7 +1045,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
ECalView *cal_view;
icaltimezone *utc;
time_t start = time (NULL), end;
- GList *comp_list, *client_list, *cl;
+ GList *comp_list = NULL, *client_list, *cl;
cal_view = E_CAL_VIEW (user_data);
@@ -972,8 +1055,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
client_list = e_cal_model_get_client_list (cal_view->priv->model);
for (cl = client_list; cl != NULL; cl = cl->next) {
- comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -1041,14 +1123,6 @@ on_paste (GtkWidget *widget, gpointer user_data)
e_cal_view_paste_clipboard (cal_view);
}
-static void
-on_unrecur_appointment (GtkWidget *widget, gpointer user_data)
-{
- ECalView *cal_view = E_CAL_VIEW (user_data);
-
- gnome_calendar_unrecur_selection (cal_view->priv->calendar);
-}
-
enum {
/*
* This is used to "flag" events that can not be editted
@@ -1142,7 +1216,6 @@ static EPopupMenu child_items [] = {
E_POPUP_SEPARATOR,
E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING),
- E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE | MASK_INSTANCE),
E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
@@ -1209,21 +1282,18 @@ setup_popup_icons (EPopupMenu *context_menu)
GtkMenu *
e_cal_view_create_popup_menu (ECalView *cal_view)
{
- gboolean being_edited, have_selection;
GList *selected;
EPopupMenu *context_menu;
guint32 disable_mask = 0, hide_mask = 0;
GtkMenu *popup;
CalClient *client = NULL;
-
+ gboolean read_only = TRUE;
+
g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
/* get the selection */
- being_edited = FALSE;
selected = e_cal_view_get_selected_events (cal_view);
- have_selection = GTK_WIDGET_HAS_FOCUS (cal_view) && selected != NULL;
-
if (selected == NULL) {
cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar);
main_items[9].submenu = cal_view->priv->view_menu;
@@ -1260,15 +1330,158 @@ e_cal_view_create_popup_menu (ECalView *cal_view)
client = event->comp_data->client;
}
- if (cal_client_is_read_only (client))
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (read_only)
disable_mask |= MASK_EDITABLE;
- if (being_edited)
- disable_mask |= MASK_EDITING;
-
setup_popup_icons (context_menu);
popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view);
g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view);
return popup;
}
+
+/**
+ * e_cal_view_new_appointment_for
+ * @cal_view: A calendar view.
+ * @dtstart: A Unix time_t that marks the beginning of the appointment.
+ * @dtend: A Unix time_t that marks the end of the appointment.
+ * @all_day: If TRUE, the dtstart and dtend are expanded to cover
+ * the entire day, and the event is set to TRANSPARENT.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an event editor dialog for a new appointment.
+ */
+void
+e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart, time_t dtend,
+ gboolean all_day,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ struct icaltimetype itt;
+ CalComponentDateTime dt;
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ CalComponentTransparency transparency;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ priv = cal_view->priv;
+
+ dt.value = &itt;
+ if (all_day)
+ dt.tzid = NULL;
+ else
+ dt.tzid = icaltimezone_get_tzid (priv->zone);
+
+ icalcomp = e_cal_model_create_component_with_defaults (priv->model);
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* DTSTART, DTEND */
+ itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
+ if (all_day) {
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtstart (comp, &dt);
+
+ itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
+ if (all_day) {
+ /* We round it up to the end of the day, unless it is
+ already set to midnight */
+ if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
+ icaltime_adjust (&itt, 1, 0, 0, 0);
+ }
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtend (comp, &dt);
+
+ /* TRANSPARENCY */
+ transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
+ : CAL_COMPONENT_TRANSP_OPAQUE;
+ cal_component_set_transparency (comp, transparency);
+
+ /* CATEGORY */
+ cal_component_set_categories (comp, priv->default_category);
+
+ /* edit the object */
+ cal_component_commit_sequence (comp);
+
+ e_cal_view_edit_appointment (cal_view,
+ e_cal_model_get_default_client (priv->model),
+ icalcomp, meeting);
+
+ g_object_unref (comp);
+}
+
+/**
+ * e_cal_view_new_appointment
+ * @cal_view: A calendar view.
+ *
+ * Opens an event editor dialog for a new appointment. The appointment's
+ * start and end times are set to the currently selected time range in
+ * the calendar view.
+ */
+void
+e_cal_view_new_appointment (ECalView *cal_view)
+{
+ time_t dtstart, dtend;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+/**
+ * e_cal_view_edit_appointment
+ * @cal_view: A calendar view.
+ * @client: Calendar client.
+ * @icalcomp: The object to be edited.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an editor window to allow the user to edit the selected
+ * object.
+ */
+void
+e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ CompEditor *ce;
+ const char *uid;
+ CalComponent *comp;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+ g_return_if_fail (IS_CAL_CLIENT (client));
+ g_return_if_fail (icalcomp != NULL);
+
+ priv = cal_view->priv;
+
+ uid = icalcomponent_get_uid (icalcomp);
+
+ ce = e_comp_editor_registry_find (comp_editor_registry, uid);
+ if (!ce) {
+ EventEditor *ee;
+
+ ee = event_editor_new (client);
+ ce = COMP_EDITOR (ee);
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ comp_editor_edit_comp (ce, comp);
+ if (meeting)
+ event_editor_show_meeting (ee);
+
+ e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
+
+ g_object_unref (comp);
+ }
+
+ comp_editor_focus (ce);
+}
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index ea7c11a00d..9a09a5236a 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -96,6 +96,8 @@ ECalModel *e_cal_view_get_model (ECalView *cal_view);
void e_cal_view_set_model (ECalView *cal_view, ECalModel *model);
icaltimezone *e_cal_view_get_timezone (ECalView *cal_view);
void e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone);
+const char *e_cal_view_get_default_category (ECalView *cal_view);
+void e_cal_view_set_default_category (ECalView *cal_view, const char *category);
void e_cal_view_set_status_message (ECalView *cal_view, const gchar *message);
@@ -114,6 +116,17 @@ void e_cal_view_delete_selected_occurrence (ECalView *cal_view);
GtkMenu *e_cal_view_create_popup_menu (ECalView *cal_view);
+void e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart,
+ time_t dtend,
+ gboolean all_day,
+ gboolean meeting);
+void e_cal_view_new_appointment (ECalView *cal_view);
+void e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting);
+
G_END_DECLS
#endif
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index a2a4f09d56..b4ec9faea0 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -65,6 +65,7 @@
#include "calendar-commands.h"
#include "calendar-config.h"
#include "goto.h"
+#include "e-cal-model-calendar.h"
#include "e-day-view-time-item.h"
#include "e-day-view-top-item.h"
#include "e-day-view-layout.h"
@@ -592,8 +593,6 @@ e_day_view_init (EDayView *day_view)
day_view->auto_scroll_timeout_id = 0;
- day_view->default_category = NULL;
-
day_view->large_font_desc = NULL;
/* String to use in 12-hour time format for times in the morning. */
@@ -850,8 +849,11 @@ GtkWidget *
e_day_view_new (void)
{
GtkWidget *day_view;
+ ECalModel *model;
+
+ model = E_CAL_MODEL (e_cal_model_calendar_new ());
- day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), NULL));
+ day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), "model", model, NULL));
return day_view;
}
@@ -881,12 +883,6 @@ e_day_view_destroy (GtkObject *object)
day_view->large_font_desc = NULL;
}
- if (day_view->default_category) {
- g_free (day_view->default_category);
- day_view->default_category = NULL;
- }
-
-
if (day_view->normal_cursor) {
gdk_cursor_unref (day_view->normal_cursor);
day_view->normal_cursor = NULL;
@@ -1429,26 +1425,6 @@ e_day_view_focus_out (GtkWidget *widget, GdkEventFocus *event)
return FALSE;
}
-/**
- * e_day_view_set_default_category:
- * @day_view: A day view.
- * @category: Default category name or NULL for no category.
- *
- * Sets the default category that will be used when creating new calendar
- * components from the day view.
- **/
-void
-e_day_view_set_default_category (EDayView *day_view, const char *category)
-{
- g_return_if_fail (day_view != NULL);
- g_return_if_fail (E_IS_DAY_VIEW (day_view));
-
- if (day_view->default_category)
- g_free (day_view->default_category);
-
- day_view->default_category = g_strdup (category);
-}
-
static gboolean
e_day_view_update_event_cb (EDayView *day_view,
gint day,
@@ -1794,6 +1770,9 @@ e_day_view_find_event_from_uid (EDayView *day_view,
gint day, event_num;
const char *u;
+ if (!uid)
+ return FALSE;
+
for (day = 0; day < day_view->days_shown; day++) {
for (event_num = 0; event_num < day_view->events[day]->len;
event_num++) {
@@ -2048,7 +2027,6 @@ e_day_view_find_work_week_start (EDayView *day_view,
return icaltime_as_timet_with_zone (tt, e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
}
-
/* Returns the selected time range. */
static void
e_day_view_get_selected_time_range (ECalView *cal_view, time_t *start_time, time_t *end_time)
@@ -2123,6 +2101,8 @@ e_day_view_recalc_day_starts (EDayView *day_view,
day_view->lower = start_time;
day_view->upper = day_view->day_starts[day_view->days_shown];
+
+ e_day_view_update_query (day_view);
}
@@ -2588,9 +2568,9 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget,
time_t dtstart, dtend;
e_day_view_get_selected_time_range ((ECalView *) day_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (e_cal_view_get_calendar (E_CAL_VIEW (day_view)),
- dtstart, dtend,
- TRUE, FALSE);
+ e_cal_view_new_appointment_for (E_CAL_VIEW (day_view),
+ dtstart, dtend,
+ TRUE, FALSE);
return TRUE;
}
@@ -2709,9 +2689,9 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget,
time_t dtstart, dtend;
e_day_view_get_selected_time_range ((ECalView *) day_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (e_cal_view_get_calendar (E_CAL_VIEW (day_view)),
- dtstart, dtend,
- FALSE, FALSE);
+ e_cal_view_new_appointment_for (E_CAL_VIEW (day_view),
+ dtstart, dtend,
+ FALSE, FALSE);
return TRUE;
}
@@ -3101,7 +3081,6 @@ e_day_view_on_event_double_click (EDayView *day_view,
gint event_num)
{
EDayViewEvent *event;
- GnomeCalendar *calendar;
if (day == -1)
event = &g_array_index (day_view->long_events, EDayViewEvent,
@@ -3112,11 +3091,9 @@ e_day_view_on_event_double_click (EDayView *day_view,
e_day_view_stop_editing_event (day_view);
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (day_view));
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (day_view),
+ event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
}
static void
@@ -3207,7 +3184,6 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data)
EDayViewEvent, event_num);
if (!cal_util_component_has_recurrences (comp_data->icalcomp)
- && !cal_component_has_recurrences (event->comp_data->icalcomp)
&& cal_util_event_dates_match (event->comp_data->icalcomp, comp_data->icalcomp)) {
#if 0
g_print ("updated object's dates unchanged\n");
@@ -3228,17 +3204,18 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data)
NULL);
}
- /* Add the occurrences of the event. */
+ /* Add the occurrences of the event */
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+
add_event_data.day_view = day_view;
add_event_data.comp_data = comp_data;
cal_recur_generate_instances (comp, day_view->lower,
day_view->upper,
e_day_view_add_event, &add_event_data,
- cal_client_resolve_tzid_cb,
- comp_data->client,
+ cal_client_resolve_tzid_cb, comp_data->client,
e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
+
g_object_unref (comp);
e_day_view_queue_layout (day_view);
@@ -3258,8 +3235,6 @@ e_day_view_update_query (ECalView *cal_view)
e_day_view_free_events (day_view);
e_day_view_queue_layout (day_view);
- e_cal_view_set_status_message (E_CAL_VIEW (day_view), _("Searching"));
-
rows = e_table_model_row_count (E_TABLE_MODEL (e_cal_view_get_model (E_CAL_VIEW (day_view))));
for (r = 0; r < rows; r++) {
ECalModelComponent *comp_data;
@@ -3268,8 +3243,6 @@ e_day_view_update_query (ECalView *cal_view)
g_assert (comp_data != NULL);
process_component (day_view, comp_data);
}
-
- e_cal_view_set_status_message (E_CAL_VIEW (day_view), NULL);
}
static void
@@ -3282,67 +3255,6 @@ e_day_view_on_event_right_click (EDayView *day_view,
day, event_num);
}
-void
-e_day_view_unrecur_appointment (EDayView *day_view)
-{
- EDayViewEvent *event;
- CalComponent *comp, *new_comp;
- CalComponentDateTime date;
- struct icaltimetype itt;
-
- event = e_day_view_get_popup_menu_event (day_view);
- if (event == NULL)
- return;
-
- date.value = &itt;
- date.tzid = NULL;
-
- /* For the recurring object, we add an exception to get rid of the
- instance. */
-
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
-
- /* For the unrecurred instance we duplicate the original object,
- create a new uid for it, get rid of the recurrence rules, and set
- the start & end times to the instances times. */
- new_comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_component_set_uid (new_comp, cal_component_gen_uid ());
- cal_component_set_rdate_list (new_comp, NULL);
- cal_component_set_rrule_list (new_comp, NULL);
- cal_component_set_exdate_list (new_comp, NULL);
- cal_component_set_exrule_list (new_comp, NULL);
-
- date.value = &itt;
- date.tzid = icaltimezone_get_tzid (e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
-
- *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
- cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
- cal_component_set_dtend (new_comp, &date);
-
-
- /* Now update both CalComponents. Note that we do this last since at
- * present the updates happen synchronously so our event may disappear.
- */
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (comp);
-
- if (cal_client_update_object (event->comp_data->client, new_comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (new_comp);
-}
-
-
static EDayViewEvent*
e_day_view_get_popup_menu_event (EDayView *day_view)
{
@@ -3841,7 +3753,9 @@ e_day_view_finish_long_event_resize (EDayView *day_view)
struct icaltimetype itt;
time_t dt;
CalClient *client;
-
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+
event_num = day_view->resize_event_num;
event = &g_array_index (day_view->long_events, EDayViewEvent,
event_num);
@@ -3870,31 +3784,26 @@ e_day_view_finish_long_event_resize (EDayView *day_view)
e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
cal_component_set_dtend (comp, &date);
}
-
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
- } else {
+
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
gtk_widget_queue_draw (day_view->top_canvas);
- }
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, TRUE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_long_event_resize(): Could not update the object!");
- }
-
+ goto out;
+ }
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog (toplevel, client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
+ } else {
+ g_message (G_STRLOC ": Could not update the object!");
+ }
+ }
+
+ out:
gnome_canvas_item_hide (day_view->resize_long_event_rect_item);
day_view->resize_drag_pos = E_CAL_VIEW_POS_NONE;
@@ -3915,6 +3824,8 @@ e_day_view_finish_resize (EDayView *day_view)
struct icaltimetype itt;
time_t dt;
CalClient *client;
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
day = day_view->resize_event_day;
event_num = day_view->resize_event_num;
@@ -3957,29 +3868,26 @@ e_day_view_finish_resize (EDayView *day_view)
day_view->resize_drag_pos = E_CAL_VIEW_POS_NONE;
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ gtk_widget_queue_draw (day_view->top_canvas);
+ goto out;
+ }
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
- } else {
- gtk_widget_queue_draw (day_view->main_canvas);
- }
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
+ cal_component_commit_sequence (comp);
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)), client, comp, FALSE))
+ send_component_dialog (toplevel, client, comp, TRUE)) {
itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
-
+ } else {
+ g_message (G_STRLOC ": Could not update the object!");
+ }
+ }
+
+ out:
g_object_unref (comp);
}
@@ -4774,6 +4682,8 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
/* Add a new event covering the selected range */
icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (day_view)));
+ if (!icalcomp)
+ return FALSE;
uid = icalcomponent_get_uid (icalcomp);
comp = cal_component_new ();
@@ -4801,7 +4711,8 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
cal_component_set_dtstart (comp, &start_dt);
cal_component_set_dtend (comp, &end_dt);
- cal_component_set_categories (comp, day_view->default_category);
+ cal_component_set_categories (
+ comp, e_cal_view_get_default_category (E_CAL_VIEW (day_view)));
/* We add the event locally and start editing it. We don't send it
to the server until the user finishes editing it. */
@@ -5777,7 +5688,8 @@ e_day_view_on_editing_stopped (EDayView *day_view,
gchar *text = NULL;
CalComponentText summary;
CalComponent *comp;
-
+ gboolean on_server;
+
/* Note: the item we are passed here isn't reliable, so we just stop
the edit of whatever item was being edited. We also receive this
event twice for some reason. */
@@ -5822,8 +5734,9 @@ e_day_view_on_editing_stopped (EDayView *day_view,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- if (string_is_empty (text) &&
- !cal_comp_is_on_server (comp, event->comp_data->client)) {
+ on_server = cal_comp_is_on_server (comp, event->comp_data->client);
+
+ if (string_is_empty (text) && !on_server) {
const char *uid;
cal_component_get_uid (comp, &uid);
@@ -5845,34 +5758,34 @@ e_day_view_on_editing_stopped (EDayView *day_view,
e_day_view_update_event_label (day_view, day,
event_num);
} else if (summary.value || !string_is_empty (text)) {
+ icalcomponent *icalcomp = cal_component_get_icalcomponent (comp);
+
summary.value = text;
summary.altrep = NULL;
cal_component_set_summary (comp, &summary);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (event->comp_data->client, comp, mod)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_day_view_on_editing_stopped(): Could not update the object!");
+ if (!on_server) {
+ if (!cal_client_create_object (event->comp_data->client, icalcomp, NULL, NULL))
+ g_message (G_STRLOC ": Could not create the object!");
+ } else {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ goto out;
}
}
- } else if (cal_client_update_object (event->comp_data->client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_day_view_on_editing_stopped(): Could not update the object!");
+
+ /* FIXME When sending here, what exactly should we send? */
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+ if (cal_client_modify_object (event->comp_data->client, icalcomp, mod, NULL)) {
+ if (itip_organizer_is_user (comp, event->comp_data->client)
+ && send_component_dialog (toplevel, event->comp_data->client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ event->comp_data->client, NULL);
+ }
}
+
}
out:
@@ -6881,7 +6794,10 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget,
x, y, &day,
NULL);
if (pos != E_CAL_VIEW_POS_OUTSIDE) {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
const char *uid;
+
num_days = 1;
start_offset = 0;
end_offset = 0;
@@ -6972,33 +6888,20 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget,
if (event->canvas_item)
gnome_canvas_item_show (event->canvas_item);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
- }
- }
- } else if (cal_client_update_object (client, comp)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL))
+ return;
}
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client)
+ && send_component_dialog (toplevel, client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
g_object_unref (comp);
return;
@@ -7044,7 +6947,10 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget,
x, y, &day,
&row, NULL);
if (pos != E_CAL_VIEW_POS_OUTSIDE) {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
const char *uid;
+
num_rows = 1;
start_offset = 0;
end_offset = 0;
@@ -7109,30 +7015,20 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget,
if (event->canvas_item)
gnome_canvas_item_show (event->canvas_item);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
- }
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ g_object_unref (comp);
+ return;
}
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client)
+ && send_component_dialog (toplevel, client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
client, NULL);
- } else {
- g_message ("e_day_view_on_main_canvas_drag_data_received(): "
- "Could not update the object!");
}
g_object_unref (comp);
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 1c39fd5844..decd281127 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -453,9 +453,6 @@ struct _EDayView
gint am_string_width;
gint pm_string_width;
- /* The default category for new events */
- char *default_category;
-
/* The activity client used to show messages on the status bar. */
EvolutionActivityClient *activity;
};
@@ -472,9 +469,6 @@ GtkWidget* e_day_view_new (void);
void e_day_view_set_query (EDayView *day_view,
const char *sexp);
-void e_day_view_set_default_category (EDayView *day_view,
- const char *category);
-
/* Whether we are displaying a work-week, in which case the display always
starts on the first day of the working week. */
gboolean e_day_view_get_work_week_view (EDayView *day_view);
@@ -528,7 +522,6 @@ void e_day_view_set_week_start_day (EDayView *day_view,
gint week_start_day);
void e_day_view_delete_occurrence (EDayView *day_view);
-void e_day_view_unrecur_appointment (EDayView *day_view);
/* Returns the number of selected events (0 or 1 at present). */
gint e_day_view_get_num_events_selected (EDayView *day_view);
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index 8b39b82b8c..d5e24c8936 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -94,8 +94,6 @@ struct _EItipControlPrivate {
#define HTML_BODY_END "</body>"
#define HTML_FOOTER "</html>"
-extern EvolutionShellClient *global_shell_client;
-
/* We intentionally use "calendar" instead of "calendar / *" here. We
* don't want public calendars.
*/
@@ -132,63 +130,26 @@ class_init (EItipControlClass *klass)
object_class->finalize = finalize;
}
-
-/* Calendar Server routines */
-static void
-start_calendar_server_cb (CalClient *cal_client,
- CalClientOpenStatus status,
- gpointer data)
-{
- int *success = data;
- int orig = *success;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS)
- *success = 1;
- else
- *success = 0;
-
- if (orig != -1)
- gtk_main_quit (); /* end the sub event loop */
-}
-
static CalClient *
start_calendar_server (EItipControl *itip, char *uri)
{
CalClient *client;
- int success = -1;
-
- client = cal_client_new ();
-
- g_signal_connect (client, "cal_opened", G_CALLBACK (start_calendar_server_cb), &success);
-
- if (!cal_client_open_calendar (client, uri, TRUE))
- goto error;
-
- /* run a sub event loop to turn cal-client's async load
- notification into a synchronous call */
- if (success == -1 && !itip->priv->destroyed) {
- success = 0;
-
- gtk_signal_connect (GTK_OBJECT (itip), "destroy",
- gtk_main_quit, NULL);
-
- gtk_main ();
-
- gtk_signal_disconnect_by_func (GTK_OBJECT (itip),
- gtk_main_quit, NULL);
- }
+ GError *error = NULL;
- if (success == 1)
- return client;
+ client = cal_client_new (uri, CALOBJ_TYPE_EVENT);
-error:
- g_object_unref (client);
+ if (!cal_client_open (client, TRUE, &error)) {
+ g_warning (_("start_calendar_server(): %s"), error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return NULL;
+ }
- return NULL;
+ return client;
}
static gboolean
-start_default_server_async (EItipControl *itip, CalClient *client, gboolean tasks)
+start_default_server (EItipControl *itip, CalClient *client, gboolean tasks)
{
if (tasks)
return cal_client_open_default_tasks (client, FALSE);
@@ -196,6 +157,7 @@ start_default_server_async (EItipControl *itip, CalClient *client, gboolean task
return cal_client_open_default_calendar (client, FALSE);
}
+#if 0 /* EPFIXME, rewrite this */
static GPtrArray *
get_servers (EItipControl *itip, EvolutionShellClient *shell_client, const char *possible_types[], gboolean tasks)
{
@@ -263,6 +225,7 @@ get_servers (EItipControl *itip, EvolutionShellClient *shell_client, const char
return servers;
}
+#endif
static CalClient *
find_server (GPtrArray *servers, CalComponent *comp)
@@ -274,11 +237,9 @@ find_server (GPtrArray *servers, CalComponent *comp)
for (i = 0; i < servers->len; i++) {
CalClient *client;
icalcomponent *icalcomp;
- CalClientGetStatus status;
client = g_ptr_array_index (servers, i);
- status = cal_client_get_object (client, uid, &icalcomp);
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (client, uid, NULL, &icalcomp, NULL)) {
icalcomponent_free (icalcomp);
g_object_ref (client);
@@ -540,8 +501,7 @@ find_attendee (icalcomponent *ical_comp, const char *address)
for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY);
prop != NULL;
- prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY))
- {
+ prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) {
icalvalue *value;
const char *attendee;
char *text;
@@ -762,6 +722,7 @@ write_recurrence_piece (EItipControl *itip, CalComponent *comp,
} else if (!icaltime_is_null_time (r->until)) {
CalComponentDateTime dt;
+ /* FIXME This should get the tzid id, not the whole zone */
dt.value = &r->until;
dt.tzid = r->until.zone;
@@ -1220,7 +1181,7 @@ get_real_item (EItipControl *itip)
CalComponent *comp;
icalcomponent *icalcomp;
CalComponentVType type;
- CalClientGetStatus status = CAL_CLIENT_GET_NOT_FOUND;
+ gboolean found = FALSE;
const char *uid;
priv = itip->priv;
@@ -1231,17 +1192,17 @@ get_real_item (EItipControl *itip)
switch (type) {
case CAL_COMPONENT_EVENT:
if (priv->event_client != NULL)
- status = cal_client_get_object (priv->event_client, uid, &icalcomp);
+ found = cal_client_get_object (priv->event_client, uid, NULL, &icalcomp, NULL);
break;
case CAL_COMPONENT_TODO:
if (priv->task_client != NULL)
- status = cal_client_get_object (priv->task_client, uid, &icalcomp);
+ found = cal_client_get_object (priv->task_client, uid, NULL, &icalcomp, NULL);
break;
default:
- status = CAL_CLIENT_GET_NOT_FOUND;
+ found = FALSE;
}
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!found)
return NULL;
comp = cal_component_new ();
@@ -1568,13 +1529,18 @@ show_current (EItipControl *itip)
switch (type) {
case CAL_COMPONENT_EVENT:
- if (!priv->event_clients)
- priv->event_clients = get_servers (itip, global_shell_client, calendar_types, FALSE);
+ if (!priv->event_clients) {
+ priv->event_clients = g_ptr_array_new ();
+ /* EPFIXME */
+ /* priv->event_clients = get_servers (itip, global_shell_client, calendar_types, FALSE); */
+ }
show_current_event (itip);
break;
case CAL_COMPONENT_TODO:
- if (!priv->task_clients)
- priv->task_clients = get_servers (itip, global_shell_client, tasks_types, TRUE);
+ if (!priv->task_clients) {
+ /* EPFIXME */
+ /* priv->task_clients = get_servers (itip, global_shell_client, tasks_types, TRUE); */
+ }
show_current_todo (itip);
break;
case CAL_COMPONENT_FREEBUSY:
@@ -1853,7 +1819,6 @@ update_item (EItipControl *itip)
CalClient *client;
CalComponentVType type;
GtkWidget *dialog;
- CalClientResult result;
priv = itip->priv;
@@ -1881,32 +1846,18 @@ update_item (EItipControl *itip)
icalcomponent_add_component (priv->top_level, clone);
icalcomponent_set_method (priv->top_level, priv->method);
- result = cal_client_update_objects (client, priv->top_level);
- switch (result) {
- case CAL_CLIENT_RESULT_INVALID_OBJECT :
- dialog = gnome_warning_dialog (_("Object is invalid and cannot be updated\n"));
- break;
- case CAL_CLIENT_RESULT_CORBA_ERROR :
- dialog = gnome_warning_dialog (_("There was an error on the CORBA system\n"));
- break;
- case CAL_CLIENT_RESULT_NOT_FOUND :
- dialog = gnome_warning_dialog (_("Object could not be found\n"));
- break;
- case CAL_CLIENT_RESULT_PERMISSION_DENIED :
- dialog = gnome_warning_dialog (_("You do not have the right permissions to update the calendar\n"));
- break;
- case CAL_CLIENT_RESULT_SUCCESS :
- dialog = gnome_ok_dialog (_("Update complete\n"));
- break;
- default :
+ /* FIXME Better error dialog */
+ if (!cal_client_receive_objects (client, priv->top_level, NULL)) {
dialog = gnome_warning_dialog (_("Calendar file could not be updated!\n"));
- break;
+ } else {
+ dialog = gnome_ok_dialog (_("Update complete\n"));
}
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
icalcomponent_remove_component (priv->top_level, clone);
}
+#if 0
static void
update_attendee_status (EItipControl *itip)
{
@@ -1936,7 +1887,7 @@ update_attendee_status (EItipControl *itip)
/* Obtain our version */
cal_component_get_uid (priv->comp, &uid);
- status = cal_client_get_object (client, uid, &icalcomp);
+ status = cal_client_get_object (client, uid, NULL, &icalcomp);
if (status == CAL_CLIENT_GET_SUCCESS) {
GSList *attendees;
@@ -2010,6 +1961,7 @@ update_attendee_status (EItipControl *itip)
g_object_unref (comp);
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
}
+#endif
static void
remove_item (EItipControl *itip)
@@ -2019,7 +1971,7 @@ remove_item (EItipControl *itip)
CalComponentVType type;
const char *uid;
GtkWidget *dialog;
- CalClientResult result;
+ GError *error = NULL;
priv = itip->priv;
@@ -2033,13 +1985,15 @@ remove_item (EItipControl *itip)
return;
cal_component_get_uid (priv->comp, &uid);
- result = cal_client_remove_object (client, uid);
- if (result == CAL_CLIENT_RESULT_SUCCESS || result == CAL_CLIENT_RESULT_NOT_FOUND) {
+ cal_client_remove_object (client, uid, &error);
+ if (!error || error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
dialog = gnome_ok_dialog (_("Removal Complete"));
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
} else {
- delete_error_dialog (result, type);
- }
+ delete_error_dialog (error, type);
+ }
+
+ g_clear_error (&error);
}
static void
@@ -2081,7 +2035,7 @@ send_freebusy (EItipControl *itip)
CalComponentDateTime datetime;
time_t start, end;
GtkWidget *dialog;
- GList *comp_list;
+ GList *comp_list = NULL;
icaltimezone *zone;
priv = itip->priv;
@@ -2106,9 +2060,7 @@ send_freebusy (EItipControl *itip)
end = icaltime_as_timet_with_zone (*datetime.value, zone);
cal_component_free_datetime (&datetime);
- comp_list = cal_client_get_free_busy (priv->event_client, NULL, start, end);
-
- if (comp_list) {
+ if (cal_client_get_free_busy (priv->event_client, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -2210,6 +2162,7 @@ default_server_started_cb (CalClient *client, CalClientOpenStatus status, gpoint
vtype = cal_component_get_vtype (priv->comp);
switch (vtype) {
+#if 0 /* EPFIXME */
case CAL_COMPONENT_EVENT:
button = evolution_folder_selector_button_new (
global_shell_client, _("Select Calendar Folder"),
@@ -2222,6 +2175,7 @@ default_server_started_cb (CalClient *client, CalClientOpenStatus status, gpoint
calendar_config_default_tasks_folder (),
tasks_types);
break;
+#endif
default:
button = NULL;
}
@@ -2251,29 +2205,30 @@ object_requested_cb (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
context = g_new0 (ObjectRequestContext, 1);
context->itip = itip;
context->eb = eb;
- context->client = cal_client_new ();
-
- g_object_ref (itip);
- g_signal_connect (context->client, "cal_opened",
- G_CALLBACK (default_server_started_cb), context);
+ /* FIXME: use the default URIs */
switch (vtype) {
case CAL_COMPONENT_EVENT:
- success = start_default_server_async (itip, context->client, FALSE);
+ context->client = cal_client_new ("", CALOBJ_TYPE_EVENT);
+ success = start_default_server (itip, context->client, FALSE);
break;
case CAL_COMPONENT_TODO:
- success = start_default_server_async (itip, context->client, TRUE);
+ context->client = cal_client_new ("", CALOBJ_TYPE_TODO);
+ success = start_default_server (itip, context->client, TRUE);
break;
default:
- success = FALSE;
+ g_free (context);
+ return FALSE;
}
if (!success) {
- g_object_unref (itip);
g_object_unref (context->client);
g_free (context);
+ return FALSE;
}
+ g_object_ref (itip);
+
return TRUE;
}
@@ -2330,7 +2285,8 @@ ok_clicked_cb (GtkHTML *html, const gchar *method, const gchar *url, const gchar
send_freebusy (itip);
break;
case 'R':
- update_attendee_status (itip);
+ /* FIXME Make sure this does the right thing in the backend */
+ update_item (itip);
break;
case 'S':
send_item (itip);
diff --git a/calendar/gui/e-meeting-list-view.c b/calendar/gui/e-meeting-list-view.c
index 7d3a4ce6c6..64463fdcb6 100644
--- a/calendar/gui/e-meeting-list-view.c
+++ b/calendar/gui/e-meeting-list-view.c
@@ -35,11 +35,7 @@
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
-#include <ebook/e-card-types.h>
-#include <ebook/e-card-cursor.h>
-#include <ebook/e-card.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-vcard.h>
#include <cal-util/cal-component.h>
#include <cal-util/cal-util.h>
#include <cal-util/timeutil.h>
@@ -47,6 +43,7 @@
#include "calendar-config.h"
#include "e-meeting-list-view.h"
#include <misc/e-cell-renderer-combo.h>
+#include <addressbook/util/eab-destination.h>
#include "e-select-names-renderer.h"
#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
@@ -56,8 +53,6 @@ struct _EMeetingListViewPrivate
EMeetingStore *store;
EBook *ebook;
- gboolean book_loaded;
- gboolean book_load_wait;
GNOME_Evolution_Addressbook_SelectNames corba_select_names;
};
@@ -78,26 +73,17 @@ static icalparameter_role roles[] = {ICAL_ROLE_CHAIR,
static GtkTreeViewClass *parent_class = NULL;
static void
-book_open_cb (EBook *book, EBookStatus status, gpointer data)
-{
- EMeetingListView *view = E_MEETING_LIST_VIEW (data);
-
- if (status == E_BOOK_STATUS_SUCCESS)
- view->priv->book_loaded = TRUE;
- else
- g_warning ("Book not loaded");
-
- if (view->priv->book_load_wait) {
- view->priv->book_load_wait = FALSE;
- gtk_main_quit ();
- }
-}
-
-static void
start_addressbook_server (EMeetingListView *view)
{
+ GError *error = NULL;
+
view->priv->ebook = e_book_new ();
- e_book_load_default_book (view->priv->ebook, book_open_cb, view);
+ if (!e_book_load_local_addressbook (view->priv->ebook, &error)) {
+ g_warning ("start_addressbook_server(): %s", error->message);
+ g_error_free (error);
+
+ return;
+ }
}
static void
@@ -319,49 +305,41 @@ e_meeting_list_view_column_set_visible (EMeetingListView *view, const gchar *col
}
static void
-process_section (EMeetingListView *view, GNOME_Evolution_Addressbook_SimpleCardList *cards, icalparameter_role role)
+process_section (EMeetingListView *view, EABDestination **cards, icalparameter_role role)
{
EMeetingListViewPrivate *priv;
int i;
priv = view->priv;
- for (i = 0; i < cards->_length; i++) {
- const char *name, *attendee = NULL, *attr;
- GNOME_Evolution_Addressbook_SimpleCard card;
- CORBA_Environment ev;
+ for (i = 0; i < G_N_ELEMENTS (cards); i++) {
+ const char *name, *attendee = NULL;
+ char *attr = NULL;
- card = cards->_buffer[i];
-
- CORBA_exception_init (&ev);
-
- /* Get the CN */
- name = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_FullName, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
+ name = eab_destination_get_name (cards[i]);
/* Get the field as attendee from the backend */
- attr = cal_client_get_ldap_attribute (e_meeting_store_get_cal_client (priv->store));
- if (attr) {
+ if (cal_client_get_ldap_attribute (e_meeting_store_get_cal_client (priv->store),
+ &attr, NULL)) {
/* FIXME this should be more general */
- if (!g_ascii_strcasecmp (attr, "icscalendar"))
- attendee = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_Icscalendar, &ev);
+ if (!g_ascii_strcasecmp (attr, "icscalendar")) {
+ EContact *contact;
+
+ /* FIXME: this does not work, have to use first
+ eab_destination_use_contact() */
+ contact = eab_destination_get_contact (cards[i]);
+ if (contact) {
+ attendee = e_contact_get (contact, E_CONTACT_FREEBUSY_URL);
+ if (!attendee)
+ attendee = e_contact_get (contact, E_CONTACT_CALENDAR_URI);
+ }
+ }
}
- CORBA_exception_init (&ev);
-
/* If we couldn't get the attendee prior, get the email address as the default */
if (attendee == NULL || *attendee == '\0') {
- attendee = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_Email, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
+ attendee = eab_destination_get_email (cards[i]);
}
- CORBA_exception_free (&ev);
-
if (attendee == NULL || *attendee == '\0')
continue;
@@ -381,22 +359,21 @@ static void
select_names_ok_cb (BonoboListener *listener, const char *event_name, const CORBA_any *arg, CORBA_Environment *ev, gpointer data)
{
EMeetingListView *view = E_MEETING_LIST_VIEW (data);
- BonoboArg *card_arg;
int i;
for (i = 0; sections[i] != NULL; i++) {
+ EABDestination **destv;
+ char *string = NULL;
Bonobo_Control corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
(view->priv->corba_select_names, sections[i], ev);
GtkWidget *control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL);
- BonoboControlFrame *control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget));
- Bonobo_PropertyBag pb = bonobo_control_frame_get_control_property_bag (control_frame, NULL);
- card_arg = bonobo_property_bag_client_get_value_any (pb, "simple_card_list", NULL);
- if (card_arg != NULL) {
- GNOME_Evolution_Addressbook_SimpleCardList cards;
- cards = BONOBO_ARG_GET_GENERAL (card_arg, TC_GNOME_Evolution_Addressbook_SimpleCardList,
- GNOME_Evolution_Addressbook_SimpleCardList, NULL);
- process_section (view, &cards, roles[i]);
- bonobo_arg_release (card_arg);
+
+ bonobo_widget_get_property (BONOBO_WIDGET (control_widget), "destinations",
+ TC_CORBA_string, &string, NULL);
+ destv = eab_destination_importv (string);
+ if (destv) {
+ process_section (view, destv, roles[i]);
+ g_free (destv);
}
}
}
diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c
new file mode 100644
index 0000000000..4742116cf2
--- /dev/null
+++ b/calendar/gui/e-meeting-model.c
@@ -0,0 +1,1780 @@
+/* -*- Mod:e C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* itip-model.c
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: JP Rosevear
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-widget.h>
+#include <bonobo/bonobo-exception.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <gal/e-table/e-table-without.h>
+#include <gal/e-table/e-cell-text.h>
+#include <gal/e-table/e-cell-popup.h>
+#include <gal/e-table/e-cell-combo.h>
+#include <addressbook/util/eab-destination.h>
+#include <ebook/e-book.h>
+#include <ebook/e-book-async.h>
+#include <ebook/e-contact.h>
+#include <cal-util/cal-component.h>
+#include <cal-util/cal-util.h>
+#include <cal-util/timeutil.h>
+#include "Evolution-Addressbook-SelectNames.h"
+#include "calendar-config.h"
+#include "itip-utils.h"
+#include "e-meeting-utils.h"
+#include "e-meeting-attendee.h"
+#include "e-meeting-model.h"
+
+#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
+
+struct _EMeetingModelPrivate
+{
+ GPtrArray *attendees;
+
+ GList *tables;
+
+ CalClient *client;
+ icaltimezone *zone;
+
+ EBook *ebook;
+ gboolean book_loaded;
+ gboolean book_load_wait;
+
+ GPtrArray *refresh_queue;
+ GHashTable *refresh_data;
+ guint refresh_idle_id;
+
+ /* For invite others dialogs */
+ GNOME_Evolution_Addressbook_SelectNames corba_select_names;
+};
+
+#define BUF_SIZE 1024
+
+static char *sections[] = {N_("Chair Persons"),
+ N_("Required Participants"),
+ N_("Optional Participants"),
+ N_("Resources"),
+ NULL};
+static icalparameter_role roles[] = {ICAL_ROLE_CHAIR,
+ ICAL_ROLE_REQPARTICIPANT,
+ ICAL_ROLE_OPTPARTICIPANT,
+ ICAL_ROLE_NONPARTICIPANT,
+ ICAL_ROLE_NONE};
+
+typedef struct _EMeetingModelQueueData EMeetingModelQueueData;
+struct _EMeetingModelQueueData {
+ EMeetingModel *im;
+ EMeetingAttendee *ia;
+
+ gboolean refreshing;
+
+ EMeetingTime start;
+ EMeetingTime end;
+
+ char buffer[BUF_SIZE];
+ GString *string;
+
+ GPtrArray *call_backs;
+ GPtrArray *data;
+};
+
+
+static void class_init (EMeetingModelClass *klass);
+static void init (EMeetingModel *model);
+static void finalize (GObject *obj);
+
+static void refresh_queue_add (EMeetingModel *im, int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+static void refresh_queue_remove (EMeetingModel *im,
+ EMeetingAttendee *ia);
+static gboolean refresh_busy_periods (gpointer data);
+
+static void attendee_changed_cb (EMeetingAttendee *ia, gpointer data);
+static void select_names_ok_cb (BonoboListener *listener,
+ const char *event_name,
+ const CORBA_any *arg,
+ CORBA_Environment *ev,
+ gpointer data);
+
+static void table_destroy_state_cb (ETableScrolled *etable, gpointer data);
+static void table_destroy_list_cb (ETableScrolled *etable, gpointer data);
+
+static ETableModelClass *parent_class = NULL;
+
+E_MAKE_TYPE (e_meeting_model, "EMeetingModel", EMeetingModel,
+ class_init, init, E_TABLE_MODEL_TYPE);
+
+static void
+book_open_cb (EBook *book, EBookStatus status, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ priv->ebook = book;
+
+ if (status == E_BOOK_ERROR_OK)
+ priv->book_loaded = TRUE;
+ else
+ g_warning ("Book not loaded");
+
+ if (priv->book_load_wait) {
+ priv->book_load_wait = FALSE;
+ gtk_main_quit ();
+ }
+}
+
+static void
+start_addressbook_server (EMeetingModel *im)
+{
+ e_book_async_get_default_addressbook (book_open_cb, im);
+}
+
+static EMeetingAttendee *
+find_match (EMeetingModel *im, const char *address, int *pos)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ const gchar *ia_address;
+ int i;
+
+ priv = im->priv;
+
+ if (address == NULL)
+ return NULL;
+
+ /* Make sure we can add the new delegatee person */
+ for (i = 0; i < priv->attendees->len; i++) {
+ ia = g_ptr_array_index (priv->attendees, i);
+
+ ia_address = e_meeting_attendee_get_address (ia);
+ if (ia_address != NULL && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) {
+ if (pos != NULL)
+ *pos = i;
+ return ia;
+ }
+ }
+
+ return NULL;
+}
+
+static icalparameter_cutype
+text_to_type (const char *type)
+{
+ if (!g_strcasecmp (type, _("Individual")))
+ return ICAL_CUTYPE_INDIVIDUAL;
+ else if (!g_strcasecmp (type, _("Group")))
+ return ICAL_CUTYPE_GROUP;
+ else if (!g_strcasecmp (type, _("Resource")))
+ return ICAL_CUTYPE_RESOURCE;
+ else if (!g_strcasecmp (type, _("Room")))
+ return ICAL_CUTYPE_ROOM;
+ else
+ return ICAL_CUTYPE_NONE;
+}
+
+static char *
+type_to_text (icalparameter_cutype type)
+{
+ switch (type) {
+ case ICAL_CUTYPE_INDIVIDUAL:
+ return _("Individual");
+ case ICAL_CUTYPE_GROUP:
+ return _("Group");
+ case ICAL_CUTYPE_RESOURCE:
+ return _("Resource");
+ case ICAL_CUTYPE_ROOM:
+ return _("Room");
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+
+}
+
+static icalparameter_role
+text_to_role (const char *role)
+{
+ if (!g_strcasecmp (role, _("Chair")))
+ return ICAL_ROLE_CHAIR;
+ else if (!g_strcasecmp (role, _("Required Participant")))
+ return ICAL_ROLE_REQPARTICIPANT;
+ else if (!g_strcasecmp (role, _("Optional Participant")))
+ return ICAL_ROLE_OPTPARTICIPANT;
+ else if (!g_strcasecmp (role, _("Non-Participant")))
+ return ICAL_ROLE_NONPARTICIPANT;
+ else
+ return ICAL_ROLE_NONE;
+}
+
+static char *
+role_to_text (icalparameter_role role)
+{
+ switch (role) {
+ case ICAL_ROLE_CHAIR:
+ return _("Chair");
+ case ICAL_ROLE_REQPARTICIPANT:
+ return _("Required Participant");
+ case ICAL_ROLE_OPTPARTICIPANT:
+ return _("Optional Participant");
+ case ICAL_ROLE_NONPARTICIPANT:
+ return _("Non-Participant");
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+}
+
+static gboolean
+text_to_boolean (const char *role)
+{
+ if (!g_strcasecmp (role, _("Yes")))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static char *
+boolean_to_text (gboolean b)
+{
+ if (b)
+ return _("Yes");
+ else
+ return _("No");
+}
+
+static icalparameter_partstat
+text_to_partstat (const char *partstat)
+{
+ if (!g_strcasecmp (partstat, _("Needs Action")))
+ return ICAL_PARTSTAT_NEEDSACTION;
+ else if (!g_strcasecmp (partstat, _("Accepted")))
+ return ICAL_PARTSTAT_ACCEPTED;
+ else if (!g_strcasecmp (partstat, _("Declined")))
+ return ICAL_PARTSTAT_DECLINED;
+ else if (!g_strcasecmp (partstat, _("Tentative")))
+ return ICAL_PARTSTAT_TENTATIVE;
+ else if (!g_strcasecmp (partstat, _("Delegated")))
+ return ICAL_PARTSTAT_DELEGATED;
+ else if (!g_strcasecmp (partstat, _("Completed")))
+ return ICAL_PARTSTAT_COMPLETED;
+ else if (!g_strcasecmp (partstat, _("In Process")))
+ return ICAL_PARTSTAT_INPROCESS;
+ else
+ return ICAL_PARTSTAT_NONE;
+}
+
+static char *
+partstat_to_text (icalparameter_partstat partstat)
+{
+ switch (partstat) {
+ case ICAL_PARTSTAT_NEEDSACTION:
+ return _("Needs Action");
+ case ICAL_PARTSTAT_ACCEPTED:
+ return _("Accepted");
+ case ICAL_PARTSTAT_DECLINED:
+ return _("Declined");
+ case ICAL_PARTSTAT_TENTATIVE:
+ return _("Tentative");
+ case ICAL_PARTSTAT_DELEGATED:
+ return _("Delegated");
+ case ICAL_PARTSTAT_COMPLETED:
+ return _("Completed");
+ case ICAL_PARTSTAT_INPROCESS:
+ return _("In Process");
+ case ICAL_PARTSTAT_NONE:
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+}
+
+static int
+column_count (ETableModel *etm)
+{
+ return E_MEETING_MODEL_COLUMN_COUNT;
+}
+
+static int
+row_count (ETableModel *etm)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ return (priv->attendees->len);
+}
+
+static void
+append_row (ETableModel *etm, ETableModel *source, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ char *address;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ address = (char *) e_table_model_value_at (source, E_MEETING_MODEL_ADDRESS_COL, row);
+ if (find_match (im, address, NULL) != NULL) {
+ return;
+ }
+
+ ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ());
+
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address));
+ e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_MEMBER_COL, row)));
+ e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, E_MEETING_MODEL_TYPE_COL, row)));
+ e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, E_MEETING_MODEL_ROLE_COL, row)));
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, E_MEETING_MODEL_RSVP_COL, row)));
+ e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELTO_COL, row)));
+ e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELFROM_COL, row)));
+ e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, E_MEETING_MODEL_STATUS_COL, row)));
+ e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_CN_COL, row)));
+ e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_LANGUAGE_COL, row)));
+
+ e_meeting_model_add_attendee (E_MEETING_MODEL (etm), ia);
+ g_object_unref (ia);
+}
+
+static void *
+value_at (ETableModel *etm, int col, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_address (ia));
+ case E_MEETING_MODEL_MEMBER_COL:
+ return (void *)e_meeting_attendee_get_member (ia);
+ case E_MEETING_MODEL_TYPE_COL:
+ return type_to_text (e_meeting_attendee_get_cutype (ia));
+ case E_MEETING_MODEL_ROLE_COL:
+ return role_to_text (e_meeting_attendee_get_role (ia));
+ case E_MEETING_MODEL_RSVP_COL:
+ return boolean_to_text (e_meeting_attendee_get_rsvp (ia));
+ case E_MEETING_MODEL_DELTO_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_delto (ia));
+ case E_MEETING_MODEL_DELFROM_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_delfrom (ia));
+ case E_MEETING_MODEL_STATUS_COL:
+ return partstat_to_text (e_meeting_attendee_get_status (ia));
+ case E_MEETING_MODEL_CN_COL:
+ return (void *)e_meeting_attendee_get_cn (ia);
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ return (void *)e_meeting_attendee_get_language (ia);
+ }
+
+ return NULL;
+}
+
+static void
+set_value_at (ETableModel *etm, int col, int row, const void *val)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ icalparameter_cutype type;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+
+ e_table_model_pre_change (etm);
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ if (val != NULL && *((char *)val))
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", (char *) val));
+ break;
+ case E_MEETING_MODEL_MEMBER_COL:
+ e_meeting_attendee_set_member (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_TYPE_COL:
+ type = text_to_type (val);
+ e_meeting_attendee_set_cutype (ia, text_to_type (val));
+ if (type == ICAL_CUTYPE_RESOURCE) {
+ e_meeting_attendee_set_role (ia, ICAL_ROLE_NONPARTICIPANT);
+ e_table_model_cell_changed (etm, E_MEETING_MODEL_ROLE_COL, row);
+ }
+ break;
+ case E_MEETING_MODEL_ROLE_COL:
+ e_meeting_attendee_set_role (ia, text_to_role (val));
+ break;
+ case E_MEETING_MODEL_RSVP_COL:
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (val));
+ break;
+ case E_MEETING_MODEL_DELTO_COL:
+ e_meeting_attendee_set_delto (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_DELFROM_COL:
+ e_meeting_attendee_set_delfrom (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_STATUS_COL:
+ e_meeting_attendee_set_status (ia, text_to_partstat (val));
+ break;
+ case E_MEETING_MODEL_CN_COL:
+ e_meeting_attendee_set_cn (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ e_meeting_attendee_set_language (ia, g_strdup (val));
+ break;
+ }
+
+ e_table_model_cell_changed (etm, col, row);
+}
+
+static gboolean
+is_cell_editable (ETableModel *etm, int col, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ EMeetingAttendeeEditLevel level;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ if (col == E_MEETING_MODEL_DELTO_COL
+ || col == E_MEETING_MODEL_DELFROM_COL)
+ return FALSE;
+
+ if (row == -1)
+ return TRUE;
+ if (row >= priv->attendees->len)
+ return TRUE;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+ level = e_meeting_attendee_get_edit_level (ia);
+
+ switch (level) {
+ case E_MEETING_ATTENDEE_EDIT_FULL:
+ return TRUE;
+ case E_MEETING_ATTENDEE_EDIT_STATUS:
+ return col == E_MEETING_MODEL_STATUS_COL;
+ case E_MEETING_ATTENDEE_EDIT_NONE:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void *
+duplicate_value (ETableModel *etm, int col, const void *val)
+{
+ return g_strdup (val);
+}
+
+static void
+free_value (ETableModel *etm, int col, void *val)
+{
+ g_free (val);
+}
+
+static void *
+init_value (ETableModel *etm, int col)
+{
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_MEMBER_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_TYPE_COL:
+ return g_strdup (_("Individual"));
+ case E_MEETING_MODEL_ROLE_COL:
+ return g_strdup (_("Required Participant"));
+ case E_MEETING_MODEL_RSVP_COL:
+ return g_strdup (_("Yes"));
+ case E_MEETING_MODEL_DELTO_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_DELFROM_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_STATUS_COL:
+ return g_strdup (_("Needs Action"));
+ case E_MEETING_MODEL_CN_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ return g_strdup ("en");
+ }
+
+ return g_strdup ("");
+}
+
+static gboolean
+value_is_empty (ETableModel *etm, int col, const void *val)
+{
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ case E_MEETING_MODEL_MEMBER_COL:
+ case E_MEETING_MODEL_DELTO_COL:
+ case E_MEETING_MODEL_DELFROM_COL:
+ case E_MEETING_MODEL_CN_COL:
+ if (val && !g_strcasecmp (val, ""))
+ return TRUE;
+ else
+ return FALSE;
+ default:
+ ;
+ }
+
+ return TRUE;
+}
+
+static char *
+value_to_string (ETableModel *etm, int col, const void *val)
+{
+ return g_strdup (val);
+}
+
+static void
+class_init (EMeetingModelClass *klass)
+{
+ GObjectClass *gobject_class;
+ ETableModelClass *etm_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ etm_class = E_TABLE_MODEL_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = finalize;
+
+ etm_class->column_count = column_count;
+ etm_class->row_count = row_count;
+ etm_class->value_at = value_at;
+ etm_class->set_value_at = set_value_at;
+ etm_class->is_cell_editable = is_cell_editable;
+ etm_class->append_row = append_row;
+ etm_class->duplicate_value = duplicate_value;
+ etm_class->free_value = free_value;
+ etm_class->initialize_value = init_value;
+ etm_class->value_is_empty = value_is_empty;
+ etm_class->value_to_string = value_to_string;
+}
+
+
+static void
+init (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = g_new0 (EMeetingModelPrivate, 1);
+
+ im->priv = priv;
+
+ priv->attendees = g_ptr_array_new ();
+
+ priv->tables = NULL;
+
+ priv->client = NULL;
+ priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ());
+
+ priv->ebook = NULL;
+ priv->book_loaded = FALSE;
+ priv->book_load_wait = FALSE;
+
+ priv->refresh_queue = g_ptr_array_new ();
+ priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal);
+ priv->refresh_idle_id = 0;
+
+ priv->corba_select_names = CORBA_OBJECT_NIL;
+
+ start_addressbook_server (im);
+}
+
+static void
+finalize (GObject *obj)
+{
+ EMeetingModel *im = E_MEETING_MODEL (obj);
+ EMeetingModelPrivate *priv;
+ GList *l;
+ int i;
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++)
+ g_object_unref (g_ptr_array_index (priv->attendees, i));
+ g_ptr_array_free (priv->attendees, TRUE);
+
+ for (l = priv->tables; l != NULL; l = l->next)
+ g_signal_handlers_disconnect_matched (G_OBJECT (l->data), G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, im);
+ g_list_free (priv->tables);
+
+ if (priv->client != NULL)
+ g_object_unref (priv->client);
+
+ if (priv->ebook != NULL)
+ g_object_unref (priv->ebook);
+
+ if (priv->corba_select_names != CORBA_OBJECT_NIL) {
+ CORBA_Environment ev;
+ CORBA_exception_init (&ev);
+ bonobo_object_release_unref (priv->corba_select_names, &ev);
+ CORBA_exception_free (&ev);
+ }
+
+ while (priv->refresh_queue->len > 0)
+ refresh_queue_remove (im, g_ptr_array_index (priv->refresh_queue, 0));
+ g_ptr_array_free (priv->refresh_queue, TRUE);
+ g_hash_table_destroy (priv->refresh_data);
+
+ if (priv->refresh_idle_id)
+ g_source_remove (priv->refresh_idle_id);
+
+ g_free (priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (obj);
+}
+
+GtkObject *
+e_meeting_model_new (void)
+{
+ return g_object_new (E_TYPE_MEETING_MODEL, NULL);
+}
+
+
+CalClient *
+e_meeting_model_get_cal_client (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return priv->client;
+}
+
+void
+e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ if (priv->client != NULL)
+ g_object_unref (priv->client);
+
+ if (client != NULL)
+ g_object_ref (client);
+ priv->client = client;
+}
+
+icaltimezone *
+e_meeting_model_get_zone (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+
+ priv = im->priv;
+
+ return priv->zone;
+}
+
+void
+e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ priv->zone = zone;
+}
+
+static ETableScrolled *
+build_etable (ETableModel *model, const gchar *spec_file, const gchar *state_file)
+{
+ GtkWidget *etable;
+ ETable *real_table;
+ ETableExtras *extras;
+ GList *strings;
+ ECell *popup_cell, *cell;
+
+ extras = e_table_extras_new ();
+
+ /* For type */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Individual"));
+ strings = g_list_append (strings, (char*) _("Group"));
+ strings = g_list_append (strings, (char*) _("Resource"));
+ strings = g_list_append (strings, (char*) _("Room"));
+ strings = g_list_append (strings, (char*) _("Unknown"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "typeedit", popup_cell);
+
+ /* For role */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Chair"));
+ strings = g_list_append (strings, (char*) _("Required Participant"));
+ strings = g_list_append (strings, (char*) _("Optional Participant"));
+ strings = g_list_append (strings, (char*) _("Non-Participant"));
+ strings = g_list_append (strings, (char*) _("Unknown"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "roleedit", popup_cell);
+
+ /* For rsvp */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Yes"));
+ strings = g_list_append (strings, (char*) _("No"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "rsvpedit", popup_cell);
+
+ /* For status */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Needs Action"));
+ strings = g_list_append (strings, (char*) _("Accepted"));
+ strings = g_list_append (strings, (char*) _("Declined"));
+ strings = g_list_append (strings, (char*) _("Tentative"));
+ strings = g_list_append (strings, (char*) _("Delegated"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "statusedit", popup_cell);
+
+ etable = e_table_scrolled_new_from_spec_file (model, extras, spec_file, NULL);
+ real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (etable));
+ g_object_set (G_OBJECT (real_table), "uniform_row_height", TRUE, NULL);
+ e_table_load_state (real_table, state_file);
+
+#if 0
+ g_signal_connect (real_table, "right_click", G_CALLBACK (right_click_cb), mpage);
+#endif
+
+ g_signal_connect (etable, "destroy", G_CALLBACK (table_destroy_state_cb), g_strdup (state_file));
+
+ g_object_unref (extras);
+
+ return E_TABLE_SCROLLED (etable);
+}
+
+void
+e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ g_object_ref (ia);
+ g_ptr_array_add (priv->attendees, ia);
+
+ g_signal_connect (ia, "changed", G_CALLBACK (attendee_changed_cb), im);
+
+ e_table_model_row_inserted (E_TABLE_MODEL (im), row_count (E_TABLE_MODEL (im)) - 1);
+}
+
+EMeetingAttendee *
+e_meeting_model_add_attendee_with_defaults (EMeetingModel *im)
+{
+ EMeetingAttendee *ia;
+ char *str;
+
+ ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ());
+
+ e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ADDRESS_COL));
+ e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_MEMBER_COL));
+
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_TYPE_COL);
+ e_meeting_attendee_set_cutype (ia, text_to_type (str));
+ g_free (str);
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ROLE_COL);
+ e_meeting_attendee_set_role (ia, text_to_role (str));
+ g_free (str);
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL);
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (str));
+ g_free (str);
+
+ e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL));
+ e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELFROM_COL));
+
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_STATUS_COL);
+ e_meeting_attendee_set_status (ia, text_to_partstat (str));
+ g_free (str);
+
+ e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_CN_COL));
+ e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_LANGUAGE_COL));
+
+ e_meeting_model_add_attendee (im, ia);
+
+ return ia;
+}
+
+void
+e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+ gint i, row = -1;
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ if (ia == g_ptr_array_index (priv->attendees, i)) {
+ row = i;
+ break;
+ }
+ }
+
+ if (row != -1) {
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ g_ptr_array_remove_index (priv->attendees, row);
+ g_object_unref (ia);
+
+ e_table_model_row_deleted (E_TABLE_MODEL (im), row);
+ }
+}
+
+void
+e_meeting_model_remove_all_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ gint i, len;
+
+ priv = im->priv;
+
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ len = priv->attendees->len;
+
+ for (i = 0; i < len; i++) {
+ EMeetingAttendee *ia = g_ptr_array_index (priv->attendees, i);
+ g_object_unref (ia);
+ }
+ g_ptr_array_set_size (priv->attendees, 0);
+
+ e_table_model_rows_deleted (E_TABLE_MODEL (im), 0, len);
+}
+
+EMeetingAttendee *
+e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ int i;
+
+ priv = im->priv;
+
+ if (address == NULL)
+ return NULL;
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ const gchar *ia_address;
+
+ ia = g_ptr_array_index (priv->attendees, i);
+
+ ia_address = e_meeting_attendee_get_address (ia);
+ if (ia_address && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) {
+ if (row != NULL)
+ *row = i;
+
+ return ia;
+ }
+ }
+
+ return NULL;
+}
+
+EMeetingAttendee *
+e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+ g_return_val_if_fail (row >= 0, NULL);
+
+ priv = im->priv;
+ g_return_val_if_fail (row < priv->attendees->len, NULL);
+
+ return g_ptr_array_index (priv->attendees, row);
+}
+
+gint
+e_meeting_model_count_actual_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return e_table_model_row_count (E_TABLE_MODEL (im));
+}
+
+const GPtrArray *
+e_meeting_model_get_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return priv->attendees;
+}
+
+static icaltimezone *
+find_zone (icalproperty *ip, icalcomponent *tz_top_level)
+{
+ icalparameter *param;
+ icalcomponent *sub_comp;
+ const char *tzid;
+ icalcompiter iter;
+
+ if (tz_top_level == NULL)
+ return NULL;
+
+ param = icalproperty_get_first_parameter (ip, ICAL_TZID_PARAMETER);
+ if (param == NULL)
+ return NULL;
+ tzid = icalparameter_get_tzid (param);
+
+ iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ icalcomponent *clone;
+ const char *tz_tzid;
+
+ /* FIXME We aren't passing a property here */
+ tz_tzid = icalproperty_get_tzid (sub_comp);
+ if (!strcmp (tzid, tz_tzid)) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ clone = icalcomponent_new_clone (sub_comp);
+ icaltimezone_set_component (zone, clone);
+
+ return zone;
+ }
+
+ icalcompiter_next (&iter);
+ }
+
+ return NULL;
+}
+
+
+static void
+refresh_queue_add (EMeetingModel *im, int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ EMeetingModelQueueData *qdata;
+
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+ if (ia == NULL)
+ return;
+
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ if (qdata == NULL) {
+ qdata = g_new0 (EMeetingModelQueueData, 1);
+
+ qdata->im = im;
+ qdata->ia = ia;
+ e_meeting_attendee_clear_busy_periods (ia);
+ e_meeting_attendee_set_has_calendar_info (ia, FALSE);
+
+ qdata->start = *start;
+ qdata->end = *end;
+ qdata->string = g_string_new (NULL);
+ qdata->call_backs = g_ptr_array_new ();
+ qdata->data = g_ptr_array_new ();
+ g_ptr_array_add (qdata->call_backs, call_back);
+ g_ptr_array_add (qdata->data, data);
+
+ g_hash_table_insert (priv->refresh_data, ia, qdata);
+ } else {
+ if (e_meeting_time_compare_times (start, &qdata->start) == -1)
+ qdata->start = *start;
+ if (e_meeting_time_compare_times (end, &qdata->end) == 1)
+ qdata->end = *end;
+ g_ptr_array_add (qdata->call_backs, call_back);
+ g_ptr_array_add (qdata->data, data);
+ }
+
+ g_object_ref (ia);
+ g_ptr_array_add (priv->refresh_queue, ia);
+
+ if (priv->refresh_idle_id == 0)
+ priv->refresh_idle_id = g_idle_add (refresh_busy_periods, im);
+}
+
+static void
+refresh_queue_remove (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingModelQueueData *qdata;
+
+ priv = im->priv;
+
+ /* Free the queue data */
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ g_assert (qdata != NULL);
+
+ g_hash_table_remove (priv->refresh_data, ia);
+ g_ptr_array_free (qdata->call_backs, TRUE);
+ g_ptr_array_free (qdata->data, TRUE);
+ g_free (qdata);
+
+ /* Unref the attendee */
+ g_ptr_array_remove (priv->refresh_queue, ia);
+ g_object_unref (ia);
+}
+
+static void
+process_callbacks (EMeetingModelQueueData *qdata)
+{
+ EMeetingModel *im;
+ int i;
+
+ for (i = 0; i < qdata->call_backs->len; i++) {
+ EMeetingModelRefreshCallback call_back;
+ gpointer *data;
+
+ call_back = g_ptr_array_index (qdata->call_backs, i);
+ data = g_ptr_array_index (qdata->data, i);
+
+ call_back (data);
+ }
+
+ im = qdata->im;
+ refresh_queue_remove (qdata->im, qdata->ia);
+ g_object_unref (im);
+}
+
+static void
+process_free_busy_comp (EMeetingAttendee *ia,
+ icalcomponent *fb_comp,
+ icaltimezone *zone,
+ icalcomponent *tz_top_level)
+{
+ icalproperty *ip;
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_DTSTART_PROPERTY);
+ if (ip != NULL) {
+ struct icaltimetype dtstart;
+ icaltimezone *ds_zone;
+
+ dtstart = icalproperty_get_dtstart (ip);
+ if (!dtstart.is_utc)
+ ds_zone = find_zone (ip, tz_top_level);
+ else
+ ds_zone = icaltimezone_get_utc_timezone ();
+ icaltimezone_convert_time (&dtstart, ds_zone, zone);
+ e_meeting_attendee_set_start_busy_range (ia,
+ dtstart.year,
+ dtstart.month,
+ dtstart.day,
+ dtstart.hour,
+ dtstart.minute);
+ }
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_DTEND_PROPERTY);
+ if (ip != NULL) {
+ struct icaltimetype dtend;
+ icaltimezone *de_zone;
+
+ dtend = icalproperty_get_dtend (ip);
+ if (!dtend.is_utc)
+ de_zone = find_zone (ip, tz_top_level);
+ else
+ de_zone = icaltimezone_get_utc_timezone ();
+ icaltimezone_convert_time (&dtend, de_zone, zone);
+ e_meeting_attendee_set_end_busy_range (ia,
+ dtend.year,
+ dtend.month,
+ dtend.day,
+ dtend.hour,
+ dtend.minute);
+ }
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY);
+ while (ip != NULL) {
+ icalparameter *param;
+ struct icalperiodtype fb;
+ EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST;
+ icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY;
+
+ fb = icalproperty_get_freebusy (ip);
+ param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER);
+ if (param != NULL)
+ fbtype = icalparameter_get_fbtype (param);
+
+ switch (fbtype) {
+ case ICAL_FBTYPE_BUSY:
+ busy_type = E_MEETING_FREE_BUSY_BUSY;
+ break;
+
+ case ICAL_FBTYPE_BUSYUNAVAILABLE:
+ busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE;
+ break;
+
+ case ICAL_FBTYPE_BUSYTENTATIVE:
+ busy_type = E_MEETING_FREE_BUSY_TENTATIVE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (busy_type != E_MEETING_FREE_BUSY_LAST) {
+ icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+
+ icaltimezone_convert_time (&fb.start, utc_zone, zone);
+ icaltimezone_convert_time (&fb.end, utc_zone, zone);
+ e_meeting_attendee_add_busy_period (ia,
+ fb.start.year,
+ fb.start.month,
+ fb.start.day,
+ fb.start.hour,
+ fb.start.minute,
+ fb.end.year,
+ fb.end.month,
+ fb.end.day,
+ fb.end.hour,
+ fb.end.minute,
+ busy_type);
+ }
+
+ ip = icalcomponent_get_next_property (fb_comp, ICAL_FREEBUSY_PROPERTY);
+ }
+}
+
+static void
+process_free_busy (EMeetingModelQueueData *qdata, char *text)
+{
+ EMeetingModel *im = qdata->im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia = qdata->ia;
+ icalcomponent *main_comp;
+ icalcomponent_kind kind = ICAL_NO_COMPONENT;
+
+ priv = im->priv;
+
+ main_comp = icalparser_parse_string (text);
+ if (main_comp == NULL) {
+ process_callbacks (qdata);
+ return;
+ }
+
+ kind = icalcomponent_isa (main_comp);
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcompiter iter;
+ icalcomponent *tz_top_level, *sub_comp;
+
+ tz_top_level = cal_util_new_top_level ();
+
+ iter = icalcomponent_begin_component (main_comp, ICAL_VTIMEZONE_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ icalcomponent *clone;
+
+ clone = icalcomponent_new_clone (sub_comp);
+ icalcomponent_add_component (tz_top_level, clone);
+
+ icalcompiter_next (&iter);
+ }
+
+ iter = icalcomponent_begin_component (main_comp, ICAL_VFREEBUSY_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ process_free_busy_comp (ia, sub_comp, priv->zone, tz_top_level);
+
+ icalcompiter_next (&iter);
+ }
+ icalcomponent_free (tz_top_level);
+ } else if (kind == ICAL_VFREEBUSY_COMPONENT) {
+ process_free_busy_comp (ia, main_comp, priv->zone, NULL);
+ }
+
+ icalcomponent_free (main_comp);
+
+ process_callbacks (qdata);
+}
+
+static void
+async_close (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+
+ process_free_busy (qdata, qdata->string->str);
+}
+
+static void
+async_read (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer buffer,
+ GnomeVFSFileSize requested,
+ GnomeVFSFileSize read,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GnomeVFSFileSize buf_size = BUF_SIZE - 1;
+
+ if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ ((char *)buffer)[read] = '\0';
+ qdata->string = g_string_append (qdata->string, buffer);
+
+ if (result == GNOME_VFS_ERROR_EOF) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
+}
+
+static void
+async_open (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GnomeVFSFileSize buf_size = BUF_SIZE - 1;
+
+ if (result != GNOME_VFS_OK) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
+}
+
+static void
+contacts_cb (EBook *book, EBookStatus status, GList *contacts, gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GList *l;
+
+ if (status != E_BOOK_ERROR_OK)
+ return;
+
+ for (l = contacts; l; l = l->next) {
+ GnomeVFSAsyncHandle *handle;
+ EContact *contact = E_CONTACT (l->data);
+ const char *fburl = e_contact_get_const (contact, E_CONTACT_FREEBUSY_URL);
+
+ if (!fburl || !*fburl)
+ continue;
+
+ /* Read in free/busy data from the url */
+ gnome_vfs_async_open (&handle, fburl, GNOME_VFS_OPEN_READ,
+ GNOME_VFS_PRIORITY_DEFAULT, async_open, qdata);
+
+ e_free_object_list (contacts);
+ return;
+ }
+
+ process_callbacks (qdata);
+ e_free_object_list (contacts);
+}
+
+static gboolean
+refresh_busy_periods (gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia = NULL;
+ EMeetingModelQueueData *qdata = NULL;
+ char *query;
+ int i;
+
+ priv = im->priv;
+
+ /* Check to see if there are any remaining attendees in the queue */
+ for (i = 0; i < priv->refresh_queue->len; i++) {
+ ia = g_ptr_array_index (priv->refresh_queue, i);
+ g_assert (ia != NULL);
+
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ g_assert (qdata != NULL);
+
+ if (!qdata->refreshing)
+ break;
+ }
+
+ /* The everything in the queue is being refreshed */
+ if (i >= priv->refresh_queue->len) {
+ priv->refresh_idle_id = 0;
+ return FALSE;
+ }
+
+ /* Indicate we are trying to refresh it */
+ qdata->refreshing = TRUE;
+
+ /* We take a ref in case we get destroyed in the gui during a callback */
+ g_object_ref (qdata->im);
+
+ /* Check the server for free busy data */
+ if (priv->client) {
+ GList *fb_data = NULL, *users = NULL;
+ struct icaltimetype itt;
+ time_t startt, endt;
+ const char *user;
+
+ itt = icaltime_null_time ();
+ itt.year = g_date_year (&qdata->start.date);
+ itt.month = g_date_month (&qdata->start.date);
+ itt.day = g_date_day (&qdata->start.date);
+ itt.hour = qdata->start.hour;
+ itt.minute = qdata->start.minute;
+ startt = icaltime_as_timet_with_zone (itt, priv->zone);
+
+ itt = icaltime_null_time ();
+ itt.year = g_date_year (&qdata->end.date);
+ itt.month = g_date_month (&qdata->end.date);
+ itt.day = g_date_day (&qdata->end.date);
+ itt.hour = qdata->end.hour;
+ itt.minute = qdata->end.minute;
+ endt = icaltime_as_timet_with_zone (itt, priv->zone);
+
+ user = itip_strip_mailto (e_meeting_attendee_get_address (ia));
+ users = g_list_append (users, g_strdup (user));
+
+ /* FIXME Error checking */
+ cal_client_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL);
+
+ g_list_foreach (users, (GFunc)g_free, NULL);
+ g_list_free (users);
+
+ if (fb_data != NULL) {
+ CalComponent *comp = fb_data->data;
+ char *comp_str;
+
+ comp_str = cal_component_get_as_string (comp);
+ process_free_busy (qdata, comp_str);
+ g_free (comp_str);
+ return TRUE;
+ }
+ }
+
+ /* Look for fburl's of attendee with no free busy info on server */
+ if (!priv->book_loaded) {
+ priv->book_load_wait = TRUE;
+ gtk_main ();
+ }
+
+ if (!e_meeting_attendee_is_set_address (ia)) {
+ process_callbacks (qdata);
+ return TRUE;
+ }
+
+ query = g_strdup_printf ("(is \"email\" \"%s\")",
+ itip_strip_mailto (e_meeting_attendee_get_address (ia)));
+ if (!e_book_async_get_contacts (priv->ebook, query, contacts_cb, qdata))
+ process_callbacks (qdata);
+ g_free (query);
+
+ return TRUE;
+}
+
+void
+e_meeting_model_refresh_all_busy_periods (EMeetingModel *im,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+ int i;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++)
+ refresh_queue_add (im, i, start, end, call_back, data);
+}
+
+void
+e_meeting_model_refresh_busy_periods (EMeetingModel *im,
+ int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ refresh_queue_add (im, row, start, end, call_back, data);
+}
+
+ETableScrolled *
+e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file)
+{
+ EMeetingModelPrivate *priv;
+ ETableScrolled *ets;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+
+ priv = im->priv;
+
+ ets = build_etable (E_TABLE_MODEL (im), spec_file, state_file);
+
+ priv->tables = g_list_prepend (priv->tables, ets);
+
+ g_signal_connect (ets, "destroy", G_CALLBACK (table_destroy_list_cb), im);
+
+ return ets;
+}
+
+void
+e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add)
+{
+ EMeetingModelPrivate *priv;
+ GList *l;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ for (l = priv->tables; l != NULL; l = l->next) {
+ ETableScrolled *ets;
+ ETable *real_table;
+
+ ets = l->data;
+ real_table = e_table_scrolled_get_table (ets);
+
+ g_object_set (G_OBJECT (real_table), "use_click_to_add", click_to_add, NULL);
+ }
+}
+
+int
+e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, -1);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1);
+
+ priv = im->priv;
+
+ return e_table_model_to_view_row (et, model_row);
+}
+
+int
+e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, -1);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1);
+
+ priv = im->priv;
+
+ return e_table_view_to_model_row (et, view_row);
+}
+
+
+static void
+add_section (GNOME_Evolution_Addressbook_SelectNames corba_select_names, const char *name)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_SelectNames_addSection (corba_select_names,
+ name,
+ gettext (name),
+ &ev);
+
+ CORBA_exception_free (&ev);
+}
+
+static gboolean
+get_select_name_dialog (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ CORBA_Environment ev;
+ int i;
+
+ priv = im->priv;
+
+ if (priv->corba_select_names != CORBA_OBJECT_NIL) {
+ Bonobo_Control corba_control;
+ GtkWidget *control_widget;
+ int i;
+
+ CORBA_exception_init (&ev);
+ for (i = 0; sections[i] != NULL; i++) {
+ corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
+ (priv->corba_select_names, sections[i], &ev);
+ if (BONOBO_EX (&ev)) {
+ CORBA_exception_free (&ev);
+ return FALSE;
+ }
+
+ control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL);
+
+ bonobo_widget_set_property (BONOBO_WIDGET (control_widget), "text", TC_CORBA_string, "", NULL);
+ }
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+ }
+
+ CORBA_exception_init (&ev);
+
+ priv->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev);
+
+ for (i = 0; sections[i] != NULL; i++)
+ add_section (priv->corba_select_names, sections[i]);
+
+ bonobo_event_source_client_add_listener (priv->corba_select_names,
+ (BonoboListenerCallbackFn) select_names_ok_cb,
+ "GNOME/Evolution:ok:dialog",
+ NULL, im);
+
+ if (BONOBO_EX (&ev)) {
+ CORBA_exception_free (&ev);
+ return FALSE;
+ }
+
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+}
+
+void
+e_meeting_model_invite_others_dialog (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ CORBA_Environment ev;
+
+ priv = im->priv;
+
+ if (!get_select_name_dialog (im))
+ return;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_SelectNames_activateDialog (
+ priv->corba_select_names, _("Required Participants"), &ev);
+
+ CORBA_exception_free (&ev);
+}
+
+static void
+process_section (EMeetingModel *im, EABDestination **destv, icalparameter_role role)
+{
+ EMeetingModelPrivate *priv;
+ int i;
+
+ if (!destv)
+ return;
+
+ priv = im->priv;
+ for (i = 0; destv[i]; i++) {
+ EMeetingAttendee *ia;
+ const char *name, *attendee = NULL;
+ char *attr;
+ CORBA_Environment ev;
+ EABDestination *dest = destv[i];
+
+ CORBA_exception_init (&ev);
+
+ /* Get the CN */
+ name = eab_destination_get_name (dest);
+
+ /* Get the field as attendee from the backend */
+ if (cal_client_get_ldap_attribute (priv->client, &attr, NULL) && attr) {
+ /* FIXME this should be more general */
+ if (!strcmp (attr, "icscalendar")) {
+ EContact *contact = eab_destination_get_contact (dest);
+ if (contact)
+ attendee = e_contact_get_const (contact, E_CONTACT_ICS_CALENDAR);
+ }
+
+ g_free (attr);
+ }
+
+ CORBA_exception_init (&ev);
+
+ /* If we couldn't get the attendee prior, get the email address as the default */
+ if (attendee == NULL || *attendee == '\0') {
+ attendee = eab_destination_get_email (dest);
+ }
+
+ CORBA_exception_free (&ev);
+
+ if (attendee == NULL || *attendee == '\0')
+ continue;
+
+ if (e_meeting_model_find_attendee (im, attendee, NULL) == NULL) {
+ ia = e_meeting_model_add_attendee_with_defaults (im);
+
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", attendee));
+ e_meeting_attendee_set_role (ia, role);
+ if (role == ICAL_ROLE_NONPARTICIPANT)
+ e_meeting_attendee_set_cutype (ia, ICAL_CUTYPE_RESOURCE);
+ e_meeting_attendee_set_cn (ia, g_strdup (name));
+ }
+ }
+}
+
+static void
+select_names_ok_cb (BonoboListener *listener,
+ const char *event_name,
+ const CORBA_any *arg,
+ CORBA_Environment *ev,
+ gpointer data)
+{
+ EMeetingModel *im = data;
+ EMeetingModelPrivate *priv;
+ Bonobo_Control corba_control;
+ GtkWidget *control_widget;
+ BonoboControlFrame *control_frame;
+ Bonobo_PropertyBag pb;
+ char *dest_str;
+ EABDestination **dest;
+ int i;
+
+ priv = im->priv;
+
+ for (i = 0; sections[i] != NULL; i++) {
+ corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
+ (priv->corba_select_names, sections[i], ev);
+ control_widget = bonobo_widget_new_control_from_objref
+ (corba_control, CORBA_OBJECT_NIL);
+
+ control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget));
+ pb = bonobo_control_frame_get_control_property_bag (control_frame, NULL);
+ dest_str = bonobo_pbclient_get_string (pb, "destinations", NULL);
+ dest = eab_destination_importv (dest_str);
+ process_section (im, dest, roles[i]);
+ eab_destination_freev (dest);
+ }
+}
+
+static void
+attendee_changed_cb (EMeetingAttendee *ia, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+ gint row = -1, i;
+
+ priv = im->priv;
+
+ /* FIXME: Ideally I think you are supposed to call pre_change() before
+ the data structures are changed. */
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ if (ia == g_ptr_array_index (priv->attendees, i)) {
+ row = i;
+ break;
+ }
+ }
+
+ if (row == -1)
+ e_table_model_no_change (E_TABLE_MODEL (im));
+ else
+ e_table_model_row_changed (E_TABLE_MODEL (im), row);
+}
+
+static void
+table_destroy_state_cb (ETableScrolled *etable, gpointer data)
+{
+ ETable *real_table;
+ char *filename = data;
+
+ real_table = e_table_scrolled_get_table (etable);
+ e_table_save_state (real_table, filename);
+
+ g_free (data);
+}
+
+static void
+table_destroy_list_cb (ETableScrolled *etable, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ priv->tables = g_list_remove (priv->tables, etable);
+}
+
diff --git a/calendar/gui/e-meeting-model.h b/calendar/gui/e-meeting-model.h
new file mode 100644
index 0000000000..50fba6c7a6
--- /dev/null
+++ b/calendar/gui/e-meeting-model.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-model.h
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: JP Rosevear
+ */
+
+#ifndef _E_MEETING_MODEL_H_
+#define _E_MEETING_MODEL_H_
+
+#include <gtk/gtk.h>
+#include <gal/e-table/e-table-scrolled.h>
+#include <gal/e-table/e-table-model.h>
+#include <cal-client/cal-client.h>
+#include "e-meeting-attendee.h"
+
+G_BEGIN_DECLS
+
+#define E_TYPE_MEETING_MODEL (e_meeting_model_get_type ())
+#define E_MEETING_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MEETING_MODEL, EMeetingModel))
+#define E_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_MODEL, EMeetingModelClass))
+#define E_IS_MEETING_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MEETING_MODEL))
+#define E_IS_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_MODEL))
+
+
+typedef struct _EMeetingModel EMeetingModel;
+typedef struct _EMeetingModelPrivate EMeetingModelPrivate;
+typedef struct _EMeetingModelClass EMeetingModelClass;
+
+typedef enum {
+ E_MEETING_MODEL_ADDRESS_COL,
+ E_MEETING_MODEL_MEMBER_COL,
+ E_MEETING_MODEL_TYPE_COL,
+ E_MEETING_MODEL_ROLE_COL,
+ E_MEETING_MODEL_RSVP_COL,
+ E_MEETING_MODEL_DELTO_COL,
+ E_MEETING_MODEL_DELFROM_COL,
+ E_MEETING_MODEL_STATUS_COL,
+ E_MEETING_MODEL_CN_COL,
+ E_MEETING_MODEL_LANGUAGE_COL,
+ E_MEETING_MODEL_COLUMN_COUNT
+} EMeetingModelColumns;
+
+struct _EMeetingModel {
+ ETableModel parent;
+
+ EMeetingModelPrivate *priv;
+};
+
+struct _EMeetingModelClass {
+ ETableModelClass parent_class;
+};
+
+typedef void (* EMeetingModelRefreshCallback) (gpointer data);
+
+
+GtkType e_meeting_model_get_type (void);
+GtkObject *e_meeting_model_new (void);
+
+CalClient *e_meeting_model_get_cal_client (EMeetingModel *im);
+void e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client);
+
+icaltimezone *e_meeting_model_get_zone (EMeetingModel *im);
+void e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone);
+
+void e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia);
+EMeetingAttendee *e_meeting_model_add_attendee_with_defaults (EMeetingModel *im);
+
+void e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia);
+void e_meeting_model_remove_all_attendees (EMeetingModel *im);
+
+EMeetingAttendee *e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row);
+EMeetingAttendee *e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row);
+
+gint e_meeting_model_count_actual_attendees (EMeetingModel *im);
+const GPtrArray *e_meeting_model_get_attendees (EMeetingModel *im);
+
+void e_meeting_model_refresh_all_busy_periods (EMeetingModel *im,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+void e_meeting_model_refresh_busy_periods (EMeetingModel *im,
+ int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+
+
+/* Helpful functions */
+ETableScrolled *e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file);
+void e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add);
+int e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row);
+int e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row);
+
+void e_meeting_model_invite_others_dialog (EMeetingModel *im);
+
+G_END_DECLS
+
+#endif
diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c
index 0129756e7c..6064971d9f 100644
--- a/calendar/gui/e-meeting-store.c
+++ b/calendar/gui/e-meeting-store.c
@@ -30,7 +30,6 @@
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
#include <cal-util/cal-component.h>
#include <cal-util/cal-util.h>
#include <cal-util/timeutil.h>
@@ -50,8 +49,6 @@ struct _EMeetingStorePrivate {
icaltimezone *zone;
EBook *ebook;
- gboolean book_loaded;
- gboolean book_load_wait;
GPtrArray *refresh_queue;
GHashTable *refresh_data;
@@ -81,26 +78,10 @@ struct _EMeetingStoreQueueData {
static GObjectClass *parent_class = NULL;
static void
-book_open_cb (EBook *book, EBookStatus status, gpointer data)
-{
- EMeetingStore *store = E_MEETING_STORE (data);
-
- if (status == E_BOOK_STATUS_SUCCESS)
- store->priv->book_loaded = TRUE;
- else
- g_warning ("Book not loaded");
-
- if (store->priv->book_load_wait) {
- store->priv->book_load_wait = FALSE;
- gtk_main_quit ();
- }
-}
-
-static void
start_addressbook_server (EMeetingStore *store)
{
store->priv->ebook = e_book_new ();
- e_book_load_default_book (store->priv->ebook, book_open_cb, store);
+ e_book_load_local_addressbook (store->priv->ebook, NULL);
}
static icalparameter_cutype
@@ -914,9 +895,11 @@ find_zone (icalproperty *ip, icalcomponent *tz_top_level)
iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT);
while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
icalcomponent *clone;
+ icalproperty *prop;
const char *tz_tzid;
-
- tz_tzid = icalproperty_get_tzid (sub_comp);
+
+ prop = icalcomponent_get_first_property (sub_comp, ICAL_TZID_PROPERTY);
+ tz_tzid = icalproperty_get_tzid (prop);
if (!strcmp (tzid, tz_tzid)) {
icaltimezone *zone;
@@ -1141,7 +1124,7 @@ refresh_busy_periods (gpointer data)
/* Check the server for free busy data */
if (priv->client) {
- GList *fb_data, *users = NULL;
+ GList *fb_data = NULL, *users = NULL;
struct icaltimetype itt;
time_t startt, endt;
const char *user;
@@ -1164,7 +1147,7 @@ refresh_busy_periods (gpointer data)
user = itip_strip_mailto (e_meeting_attendee_get_address (attendee));
users = g_list_append (users, g_strdup (user));
- fb_data = cal_client_get_free_busy (priv->client, users, startt, endt);
+ cal_client_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL);
g_list_foreach (users, (GFunc)g_free, NULL);
g_list_free (users);
@@ -1181,11 +1164,6 @@ refresh_busy_periods (gpointer data)
}
/* Look for fburl's of attendee with no free busy info on server */
- if (!priv->book_loaded) {
- priv->book_load_wait = TRUE;
- gtk_main ();
- }
-
if (!e_meeting_attendee_is_set_address (attendee)) {
process_callbacks (qdata);
return TRUE;
diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c
index 157320ef16..91d915a4d7 100644
--- a/calendar/gui/e-meeting-time-sel.c
+++ b/calendar/gui/e-meeting-time-sel.c
@@ -265,6 +265,7 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
void
e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *ems)
{
+ char *filename;
GtkWidget *hbox, *vbox, *separator, *button, *label, *table;
GtkWidget *alignment, *child_hbox, *arrow, *menuitem;
GSList *group;
@@ -313,7 +314,12 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
gtk_box_pack_start (GTK_BOX (vbox), mts->attendees_vbox, TRUE, TRUE, 0);
gtk_widget_show (mts->attendees_vbox);
+
+ /* build the etable */
+ filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
+ "config", "et-header-meeting-time-sel", NULL);
mts->model = ems;
+
if (mts->model)
g_object_ref (mts->model);
diff --git a/calendar/gui/e-select-names-editable.c b/calendar/gui/e-select-names-editable.c
index 2fcc93397a..29c54c7979 100644
--- a/calendar/gui/e-select-names-editable.c
+++ b/calendar/gui/e-select-names-editable.c
@@ -25,7 +25,7 @@
#include <gtk/gtkcelleditable.h>
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-widget.h>
-#include <ebook/e-destination.h>
+#include <addressbook/util/eab-destination.h>
#include "e-select-names-editable.h"
#include "Evolution-Addressbook-SelectNames.h"
@@ -187,16 +187,16 @@ e_select_names_editable_new ()
gchar *
e_select_names_editable_get_address (ESelectNamesEditable *esne)
{
- EDestination **dest;
+ EABDestination **dest;
gchar *dest_str;
gchar *result;
g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL);
dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL);
- dest = e_destination_importv (dest_str);
- result = g_strdup (e_destination_get_email (*dest));
- e_destination_freev (dest);
+ dest = eab_destination_importv (dest_str);
+ result = g_strdup (eab_destination_get_email (*dest));
+ eab_destination_freev (dest);
return result;
}
@@ -204,16 +204,16 @@ e_select_names_editable_get_address (ESelectNamesEditable *esne)
gchar *
e_select_names_editable_get_name (ESelectNamesEditable *esne)
{
- EDestination **dest;
+ EABDestination **dest;
gchar *dest_str;
gchar *result;
g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL);
dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL);
- dest = e_destination_importv (dest_str);
- result = g_strdup (e_destination_get_name (*dest));
- e_destination_freev (dest);
+ dest = eab_destination_importv (dest_str);
+ result = g_strdup (eab_destination_get_name (*dest));
+ eab_destination_freev (dest);
return result;
}
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index b441aee09d..768b2e587c 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -572,7 +572,6 @@ GtkWidget *
e_tasks_construct (ETasks *tasks)
{
ETasksPrivate *priv;
- ECalModel *model;
g_return_val_if_fail (tasks != NULL, NULL);
g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
@@ -581,24 +580,6 @@ e_tasks_construct (ETasks *tasks)
setup_widgets (tasks);
- priv->client = cal_client_new ();
- if (!priv->client)
- return NULL;
-
- g_signal_connect (priv->client, "cal_opened",
- G_CALLBACK (cal_opened_cb), tasks);
- g_signal_connect (priv->client, "backend_error",
- G_CALLBACK (backend_error_cb), tasks);
- g_signal_connect (priv->client, "categories_changed",
- G_CALLBACK (client_categories_changed_cb), tasks);
- g_signal_connect (priv->client, "obj_updated",
- G_CALLBACK (client_obj_updated_cb), tasks);
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- g_assert (model != NULL);
-
- e_cal_model_add_client (model, priv->client);
-
return GTK_WIDGET (tasks);
}
@@ -685,6 +666,8 @@ e_tasks_open (ETasks *tasks,
EUri *uri;
char *real_uri;
char *urinopwd;
+ ECalModel *model;
+ GError *error = NULL;
g_return_val_if_fail (tasks != NULL, FALSE);
g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
@@ -704,10 +687,30 @@ e_tasks_open (ETasks *tasks,
g_free (message);
g_free (urinopwd);
- if (!cal_client_open_calendar (priv->client, real_uri, FALSE)) {
- g_message ("e_tasks_open(): Could not issue the request");
+ /* create the CalClient */
+ priv->client = cal_client_new (real_uri, CALOBJ_TYPE_TODO);
+ if (!priv->client)
+ return NULL;
+
+ g_signal_connect (priv->client, "cal_opened",
+ G_CALLBACK (cal_opened_cb), tasks);
+ g_signal_connect (priv->client, "backend_error",
+ G_CALLBACK (backend_error_cb), tasks);
+ g_signal_connect (priv->client, "categories_changed",
+ G_CALLBACK (client_categories_changed_cb), tasks);
+ g_signal_connect (priv->client, "obj_updated",
+ G_CALLBACK (client_obj_updated_cb), tasks);
+
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+ g_assert (model != NULL);
+
+ e_cal_model_add_client (model, priv->client);
+
+ if (cal_client_open (priv->client, FALSE, &error)) {
+ g_message ("e_tasks_open(): %s", error->message);
g_free (real_uri);
e_uri_free (uri);
+ g_error_free (error);
return FALSE;
}
@@ -787,7 +790,8 @@ cal_opened_cb (CalClient *client,
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
if (zone)
- cal_client_set_default_timezone (client, zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, zone, NULL);
return;
case CAL_CLIENT_OPEN_ERROR:
@@ -937,60 +941,6 @@ create_sexp (void)
return sexp;
}
-/* Callback used when a component is updated in the live query */
-static void
-query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- delete_error_dialog (cal_client_remove_object (priv->client, uid), CAL_COMPONENT_TODO);
-}
-
-/* Callback used when an evaluation error occurs when running a query */
-static void
-query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- g_warning ("eval error: %s\n", error_str);
-
- set_status_message (tasks, NULL);
-
- g_signal_handlers_disconnect_matched (priv->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
- g_object_unref (priv->query);
- priv->query = NULL;
-}
-
-static void
-query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- if (status != CAL_QUERY_DONE_SUCCESS)
- g_warning ("query done: %s\n", error_str);
-
- set_status_message (tasks, NULL);
-
- g_signal_handlers_disconnect_matched (priv->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
- g_object_unref (priv->query);
- priv->query = NULL;
-}
/**
* e_tasks_expunge:
* @tasks: A tasks control widget
@@ -1002,31 +952,32 @@ e_tasks_delete_completed (ETasks *tasks)
{
ETasksPrivate *priv;
char *sexp;
+ GList *objects, *l;
g_return_if_fail (tasks != NULL);
g_return_if_fail (E_IS_TASKS (tasks));
priv = tasks->priv;
- /* If we have a query, we are already expunging */
- if (priv->query)
- return;
+ /* FIXME Confirm expunge */
sexp = create_sexp ();
set_status_message (tasks, _("Expunging"));
- priv->query = cal_client_get_query (priv->client, sexp);
- g_free (sexp);
-
- if (!priv->query) {
+
+ if (!cal_client_get_object_list (priv->client, sexp, &objects, NULL)) {
set_status_message (tasks, NULL);
- g_message ("update_query(): Could not create the query");
+ g_warning (G_STRLOC ": Could not get the objects");
+
return;
}
+
+ for (l = objects; l; l = l->next) {
+ /* FIXME Better error handling */
+ cal_client_remove_object (priv->client, icalcomponent_get_uid (l->data), NULL);
+ }
- g_signal_connect (priv->query, "obj_updated", G_CALLBACK (query_obj_updated_cb), tasks);
- g_signal_connect (priv->query, "query_done", G_CALLBACK (query_query_done_cb), tasks);
- g_signal_connect (priv->query, "eval_error", G_CALLBACK (query_eval_error_cb), tasks);
+ set_status_message (tasks, NULL);
}
/* Callback used from the view collection when we need to display a new view */
@@ -1181,6 +1132,7 @@ e_tasks_update_all_config_settings (void)
calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->tasks_view));
if (zone)
- cal_client_set_default_timezone (priv->client, zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (priv->client, zone, NULL);
}
}
diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c
index 139f28bb13..fd68130bc5 100644
--- a/calendar/gui/e-week-view-event-item.c
+++ b/calendar/gui/e-week-view-event-item.c
@@ -890,7 +890,6 @@ e_week_view_event_item_double_click (EWeekViewEventItem *wveitem,
EWeekView *week_view;
EWeekViewEvent *event;
GnomeCanvasItem *item;
- GnomeCalendar *calendar;
item = GNOME_CANVAS_ITEM (wveitem);
@@ -902,11 +901,7 @@ e_week_view_event_item_double_click (EWeekViewEventItem *wveitem,
e_week_view_stop_editing_event (week_view);
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (week_view));
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (week_view), event->comp_data->client, event->comp_data->icalcomp, FALSE);
return TRUE;
}
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 8028bf13e6..1be94fc1de 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -62,6 +62,7 @@
#include "calendar-config.h"
#include "print.h"
#include "goto.h"
+#include "e-cal-model-calendar.h"
#include "e-week-view-event-item.h"
#include "e-week-view-layout.h"
#include "e-week-view-main-item.h"
@@ -312,8 +313,6 @@ e_week_view_init (EWeekView *week_view)
week_view->main_gc = NULL;
- week_view->default_category = NULL;
-
/* Create the small font. */
week_view->use_small_font = TRUE;
@@ -423,8 +422,11 @@ GtkWidget *
e_week_view_new (void)
{
GtkWidget *week_view;
+ ECalModel *model;
+
+ model = E_CAL_MODEL (e_cal_model_calendar_new ());
- week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL));
+ week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), "model", model, NULL));
return week_view;
}
@@ -457,11 +459,6 @@ e_week_view_destroy (GtkObject *object)
week_view->small_font_desc = NULL;
}
- if (week_view->default_category) {
- g_free (week_view->default_category);
- week_view->default_category = NULL;
- }
-
if (week_view->normal_cursor) {
gdk_cursor_unref (week_view->normal_cursor);
week_view->normal_cursor = NULL;
@@ -1149,7 +1146,7 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data)
g_object_unref (tmp_comp);
}
- /* Add the occurrences of the event. */
+ /* Add the occurrences of the event */
num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
add_event_data.week_view = week_view;
@@ -1158,8 +1155,7 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data)
week_view->day_starts[0],
week_view->day_starts[num_days],
e_week_view_add_event, &add_event_data,
- cal_client_resolve_tzid_cb,
- comp_data->client,
+ cal_client_resolve_tzid_cb, comp_data->client,
e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
g_object_unref (comp);
@@ -1178,8 +1174,6 @@ e_week_view_update_query (ECalView *cal_view)
e_week_view_free_events (week_view);
e_week_view_queue_layout (week_view);
- e_cal_view_set_status_message (E_CAL_VIEW (week_view), _("Searching"));
-
rows = e_table_model_row_count (E_TABLE_MODEL (e_cal_view_get_model (E_CAL_VIEW (week_view))));
for (r = 0; r < rows; r++) {
ECalModelComponent *comp_data;
@@ -1188,8 +1182,6 @@ e_week_view_update_query (ECalView *cal_view)
g_assert (comp_data != NULL);
process_component (week_view, comp_data);
}
-
- e_cal_view_set_status_message (E_CAL_VIEW (week_view), NULL);
}
static void
@@ -1217,27 +1209,6 @@ e_week_view_draw_shadow (EWeekView *week_view)
gdk_draw_line (window, light_gc, x1, y2, x2, y2);
}
-/**
- * e_week_view_set_default_category:
- * @week_view: A week view.
- * @category: Default category name or NULL for no category.
- *
- * Sets the default category that will be used when creating new calendar
- * components from the week view.
- **/
-void
-e_week_view_set_default_category (EWeekView *week_view, const char *category)
-{
- g_return_if_fail (week_view != NULL);
- g_return_if_fail (E_IS_WEEK_VIEW (week_view));
-
- if (week_view->default_category)
- g_free (week_view->default_category);
-
- week_view->default_category = g_strdup (category);
-}
-
-
/* This sets the selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
@@ -2015,7 +1986,7 @@ e_week_view_on_button_press (GtkWidget *widget,
return FALSE;
if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
- gnome_calendar_new_appointment (e_cal_view_get_calendar (E_CAL_VIEW (week_view)));
+ e_cal_view_new_appointment (E_CAL_VIEW (week_view));
return TRUE;
}
@@ -2876,14 +2847,11 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
{
EWeekViewEvent *event;
gint event_num, span_num;
- GnomeCalendar *calendar;
#if 0
g_print ("In e_week_view_on_text_item_event\n");
#endif
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (week_view));
-
switch (gdkevent->type) {
case GDK_KEY_PRESS:
if (gdkevent && gdkevent->key.keyval == GDK_Return) {
@@ -2912,10 +2880,9 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
event = &g_array_index (week_view->events, EWeekViewEvent,
event_num);
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (week_view),
+ event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event");
return TRUE;
@@ -3049,7 +3016,8 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
CalComponent *comp;
CalComponentText summary;
const char *uid;
-
+ gboolean on_server;
+
/* Note: the item we are passed here isn't reliable, so we just stop
the edit of whatever item was being edited. We also receive this
event twice for some reason. */
@@ -3079,8 +3047,9 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- if (string_is_empty (text) &&
- !cal_comp_is_on_server (comp, event->comp_data->client)) {
+ on_server = cal_comp_is_on_server (comp, event->comp_data->client);
+
+ if (string_is_empty (text) && !on_server) {
const char *uid;
cal_component_get_uid (comp, &uid);
@@ -3099,33 +3068,33 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
e_week_view_reshape_event_span (week_view, event_num,
span_num);
} else if (summary.value || !string_is_empty (text)) {
+ icalcomponent *icalcomp = cal_component_get_icalcomponent (comp);
+
summary.value = text;
summary.altrep = NULL;
cal_component_set_summary (comp, &summary);
-
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (event->comp_data->client, comp, mod)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (week_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_week_view_on_editing_stopped(): Could not update the object!");
+
+ if (!on_server) {
+ if (!cal_client_create_object (event->comp_data->client, icalcomp, NULL, NULL))
+ g_message (G_STRLOC ": Could not create the object!");
+ } else {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ goto out;
}
}
- } else if (cal_client_update_object (event->comp_data->client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (week_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_week_view_on_editing_stopped(): Could not update the object!");
+
+ /* FIXME When sending here, what exactly should we send? */
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view)));
+ if (cal_client_modify_object (event->comp_data->client, icalcomp, mod, NULL)) {
+ if (itip_organizer_is_user (comp, event->comp_data->client)
+ && send_component_dialog (toplevel, event->comp_data->client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ event->comp_data->client, NULL);
+ }
}
}
@@ -3182,6 +3151,10 @@ e_week_view_find_event_from_uid (EWeekView *week_view,
EWeekViewEvent *event;
gint event_num, num_events;
+ *event_num_return = -1;
+ if (!uid)
+ return FALSE;
+
num_events = week_view->events->len;
for (event_num = 0; event_num < num_events; event_num++) {
const char *u;
@@ -3291,6 +3264,8 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
/* Add a new event covering the selected range. */
icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (week_view)));
+ if (!icalcomp)
+ return FALSE;
uid = icalcomponent_get_uid (icalcomp);
comp = cal_component_new ();
@@ -3313,7 +3288,8 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
cal_component_set_dtend (comp, &date);
- cal_component_set_categories (comp, week_view->default_category);
+ cal_component_set_categories (
+ comp, e_cal_view_get_default_category (E_CAL_VIEW (week_view)));
/* We add the event locally and start editing it. We don't send it
to the server until the user finishes editing it. */
@@ -3546,63 +3522,6 @@ e_week_view_popup_menu (GtkWidget *widget)
}
void
-e_week_view_unrecur_appointment (EWeekView *week_view)
-{
- EWeekViewEvent *event;
- CalComponent *comp, *new_comp;
- CalComponentDateTime date;
- struct icaltimetype itt;
-
- if (week_view->popup_event_num == -1)
- return;
-
- event = &g_array_index (week_view->events, EWeekViewEvent,
- week_view->popup_event_num);
-
- /* For the recurring object, we add a exception to get rid of the
- instance. */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
-
- /* For the unrecurred instance we duplicate the original object,
- create a new uid for it, get rid of the recurrence rules, and set
- the start & end times to the instances times. */
- new_comp = cal_component_new ();
- cal_component_set_icalcomponent (new_comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_component_set_uid (new_comp, cal_component_gen_uid ());
- cal_component_set_rdate_list (new_comp, NULL);
- cal_component_set_rrule_list (new_comp, NULL);
- cal_component_set_exdate_list (new_comp, NULL);
- cal_component_set_exrule_list (new_comp, NULL);
-
- date.value = &itt;
- date.tzid = icaltimezone_get_tzid (e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
-
- *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
- cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
- cal_component_set_dtend (new_comp, &date);
-
- /* Now update both CalComponents. Note that we do this last since at
- present the updates happen synchronously so our event may disappear.
- */
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (comp);
-
- if (cal_client_update_object (event->comp_data->client, new_comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (new_comp);
-}
-
-void
e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item)
{
gint day;
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index c24470155d..0296c19c42 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -331,9 +331,6 @@ struct _EWeekView
gchar *pm_string;
gint am_string_width;
gint pm_string_width;
-
- /* The default category for new events */
- char *default_category;
};
struct _EWeekViewClass
@@ -353,9 +350,6 @@ void e_week_view_get_first_day_shown (EWeekView *week_view,
void e_week_view_set_first_day_shown (EWeekView *week_view,
GDate *date);
-void e_week_view_set_default_category (EWeekView *week_view,
- const char *category);
-
/* The selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
@@ -396,8 +390,6 @@ void e_week_view_set_24_hour_format (EWeekView *week_view,
void e_week_view_delete_occurrence (EWeekView *week_view);
-void e_week_view_unrecur_appointment (EWeekView *week_view);
-
/* Returns the number of selected events (0 or 1 at present). */
gint e_week_view_get_num_events_selected (EWeekView *week_view);
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index c2a0c2c61e..bcefd8eeee 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -61,8 +61,6 @@
#include "misc.h"
#include "ea-calendar.h"
-extern ECompEditorRegistry *comp_editor_registry;
-
/* Private part of the GnomeCalendar structure */
@@ -71,6 +69,8 @@ struct _GnomeCalendarPrivate {
* The Calendar Folder.
*/
+ GHashTable *clients;
+
/* Set of categories from the calendar client */
GPtrArray *cal_categories;
@@ -119,6 +119,7 @@ struct _GnomeCalendarPrivate {
/* This is the view currently shown. We use it to keep track of the
positions of the panes. range_selected is TRUE if a range of dates
was selected in the date navigator to show the view. */
+ ECalView *views[GNOME_CAL_LAST_VIEW];
GnomeCalendarViewType current_view_type;
gboolean range_selected;
@@ -145,10 +146,6 @@ struct _GnomeCalendarPrivate {
'dates-shown-changed' signal.*/
time_t visible_start;
time_t visible_end;
-
- /* Calendar query for purging old events */
- GList *exp_queries;
- time_t exp_older_than;
};
/* Signal IDs */
@@ -361,97 +358,70 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
/* Callback used when the calendar query reports of an updated object */
static void
-dn_query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
+dn_query_objects_added_cb (CalQuery *query, GList *objects, gpointer data)
{
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
- CalComponent *comp = NULL;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
-
+ GList *l;
+
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
- /* If this is an update that is not part of an ongoing query, we have to
- * retag the whole thing: an event may change dates and the
- * tag_calendar_by_comp() below would not know how to untag the old
- * dates.
- */
- if (!query_in_progress) {
- update_query (gcal);
- return;
- }
+ for (l = objects; l; l = l->next) {
+ CalComponent *comp = NULL;
- status = cal_client_get_object (cal_query_get_client (query), uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ if (!cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) {
g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
+
+ continue;
}
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("dn_query_obj_updated_cb(): Syntax error while getting object `%s'", uid);
- return;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object is no longer in the server, so do nothing */
- return;
- default:
- g_assert_not_reached ();
- return;
+ tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL,
+ FALSE, TRUE);
+ g_object_unref (comp);
}
-
- tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL,
- FALSE, TRUE);
- g_object_unref (comp);
}
-/* Callback used when the calendar query reports of a removed object */
static void
-dn_query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data)
+dn_query_objects_modified_cb (CalQuery *query, GList *objects, gpointer data)
{
GnomeCalendar *gcal;
+ GnomeCalendarPrivate *priv;
gcal = GNOME_CALENDAR (data);
+ priv = gcal->priv;
- /* Just retag the whole thing */
+ /* We have to retag the whole thing: an event may change dates
+ * and the tag_calendar_by_comp() below would not know how to
+ * untag the old dates.
+ */
update_query (gcal);
}
-/* Callback used when the calendar query is done */
+/* Callback used when the calendar query reports of a removed object */
static void
-dn_query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str,
- gpointer data)
+dn_query_objects_removed_cb (CalQuery *query, GList *uids, gpointer data)
{
GnomeCalendar *gcal;
gcal = GNOME_CALENDAR (data);
- /* FIXME */
-
- if (status != CAL_QUERY_DONE_SUCCESS)
- fprintf (stderr, "query done: %s\n", error_str);
+ /* Just retag the whole thing */
+ update_query (gcal);
}
-/* Callback used when the calendar query reports an evaluation error */
+/* Callback used when the calendar query is done */
static void
-dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
+dn_query_done_cb (CalQuery *query, ECalendarStatus status, gpointer data)
{
GnomeCalendar *gcal;
gcal = GNOME_CALENDAR (data);
- /* FIXME */
-
- fprintf (stderr, "eval error: %s\n", error_str);
+ /* FIXME Better error reporting */
+ if (status != E_CALENDAR_STATUS_OK)
+ g_warning (G_STRLOC ": Query did not successfully complete");
}
/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */
@@ -603,6 +573,7 @@ adjust_query_sexp (GnomeCalendar *gcal, const char *sexp)
start, end,
sexp);
+
g_free (start);
g_free (end);
@@ -649,22 +620,24 @@ update_query (GnomeCalendar *gcal)
/* create queries for each loaded client */
client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->day_view)));
for (l = client_list; l != NULL; l = l->next) {
- old_query = cal_client_get_query ((CalClient *) l->data, real_sexp);
- if (!old_query) {
- g_message ("update_query(): Could not create the query");
+ if (!cal_client_get_query ((CalClient *) l->data, real_sexp, &old_query, NULL)) {
+ g_warning (G_STRLOC ": Could not create the query");
+
continue;
}
- g_signal_connect (old_query, "obj_updated",
- G_CALLBACK (dn_query_obj_updated_cb), gcal);
- g_signal_connect (old_query, "obj_removed",
- G_CALLBACK (dn_query_obj_removed_cb), gcal);
+ g_signal_connect (old_query, "objects_added",
+ G_CALLBACK (dn_query_objects_added_cb), gcal);
+ g_signal_connect (old_query, "objects_modified",
+ G_CALLBACK (dn_query_objects_modified_cb), gcal);
+ g_signal_connect (old_query, "objects_removed",
+ G_CALLBACK (dn_query_objects_removed_cb), gcal);
g_signal_connect (old_query, "query_done",
- G_CALLBACK (dn_query_query_done_cb), gcal);
- g_signal_connect (old_query, "eval_error",
- G_CALLBACK (dn_query_eval_error_cb), gcal);
+ G_CALLBACK (dn_query_done_cb), gcal);
priv->dn_queries = g_list_append (priv->dn_queries, old_query);
+
+ cal_query_start (old_query);
}
g_list_free (client_list);
@@ -673,6 +646,30 @@ update_query (GnomeCalendar *gcal)
e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
}
+static void
+adjust_query_for_view (ECalView *cal_view, const char *sexp)
+{
+ char *real_sexp, *start, *end;
+ time_t ttstart, ttend;
+
+ e_cal_view_get_visible_time_range (cal_view, &ttstart, &ttend);
+
+ start = isodate_from_time_t (ttstart);
+ end = isodate_from_time_t (ttend);
+
+ real_sexp = g_strdup_printf (
+ "(and (occur-in-time-range? (make-time \"%s\")"
+ " (make-time \"%s\"))"
+ " %s)",
+ start, end, sexp);
+
+ e_cal_model_set_query (e_cal_view_get_model (cal_view), real_sexp);
+
+ g_free (start);
+ g_free (end);
+ g_free (real_sexp);
+}
+
/**
* gnome_calendar_set_query:
* @gcal: A calendar.
@@ -685,6 +682,7 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp)
{
GnomeCalendarPrivate *priv;
ECalModel *model;
+ int i;
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
@@ -701,9 +699,9 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp)
update_query (gcal);
- /* Set the query on the main view */
- model = e_cal_view_get_model (E_CAL_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- e_cal_model_set_query (model, sexp);
+ /* Set the query on the views */
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++)
+ adjust_query_for_view (E_CAL_VIEW (priv->views[i]), sexp);
/* Set the query on the task pad */
model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
@@ -747,14 +745,15 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category,
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
ECalModel *model;
+ int i;
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
- e_day_view_set_default_category (E_DAY_VIEW (priv->day_view), category);
- e_day_view_set_default_category (E_DAY_VIEW (priv->work_week_view), category);
- e_week_view_set_default_category (E_WEEK_VIEW (priv->week_view), category);
- e_week_view_set_default_category (E_WEEK_VIEW (priv->month_view), category);
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ e_cal_view_set_default_category (E_CAL_VIEW (priv->views[i]),
+ category);
+ }
model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
e_cal_model_set_default_category (model, category);
@@ -853,7 +852,6 @@ setup_widgets (GnomeCalendar *gcal)
GtkWidget *w;
gchar *filename;
ETable *etable;
- ECalModel *model;
priv = gcal->priv;
@@ -915,7 +913,8 @@ setup_widgets (GnomeCalendar *gcal)
gtk_paned_pack2 (GTK_PANED (priv->vpane), priv->todo, TRUE, TRUE);
gtk_widget_show (priv->todo);
- filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir);
+ filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
+ "TaskPad", NULL);
e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename);
g_free (filename);
@@ -977,7 +976,7 @@ setup_widgets (GnomeCalendar *gcal)
connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view));
/* The List View. */
- filename = g_strdup_printf ("%s/config/CalListView", evolution_dir);
+ filename = g_strdup_printf (".evolution/config/CalListView");
priv->list_view = e_cal_list_view_new (filename);
g_free (filename);
@@ -988,14 +987,12 @@ setup_widgets (GnomeCalendar *gcal)
connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view));
- model = (ECalModel *) e_cal_model_calendar_new ();
- e_cal_view_set_model (E_CAL_VIEW (priv->day_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->work_week_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->week_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->month_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->list_view), model);
+ priv->views[GNOME_CAL_DAY_VIEW] = E_CAL_VIEW (priv->day_view);
+ priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CAL_VIEW (priv->work_week_view);
+ priv->views[GNOME_CAL_WEEK_VIEW] = E_CAL_VIEW (priv->week_view);
+ priv->views[GNOME_CAL_MONTH_VIEW] = E_CAL_VIEW (priv->month_view);
+ priv->views[GNOME_CAL_LIST_VIEW] = E_CAL_VIEW (priv->list_view);
- g_object_unref (model);
gnome_calendar_update_config_settings (gcal, TRUE);
}
@@ -1008,6 +1005,8 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv = g_new0 (GnomeCalendarPrivate, 1);
gcal->priv = priv;
+ priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
priv->cal_categories = NULL;
priv->tasks_categories = NULL;
@@ -1027,8 +1026,6 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->visible_start = -1;
priv->visible_end = -1;
-
- priv->exp_queries = NULL;
}
/* Frees a set of categories */
@@ -1062,6 +1059,8 @@ gnome_calendar_destroy (GtkObject *object)
if (priv) {
GList *l, *client_list;
+ g_hash_table_destroy (priv->clients);
+
free_categories (priv->cal_categories);
priv->cal_categories = NULL;
@@ -1078,7 +1077,8 @@ gnome_calendar_destroy (GtkObject *object)
g_list_free (client_list);
/* Save the TaskPad layout. */
- filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir);
+ filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
+ "TaskPad", NULL);
e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename);
g_free (filename);
@@ -1120,19 +1120,6 @@ gnome_calendar_destroy (GtkObject *object)
priv->view_menus = NULL;
}
- if (priv->exp_queries) {
- GList *l;
-
- for (l = priv->exp_queries; l != NULL; l = l->next) {
- g_signal_handlers_disconnect_matched ((CalQuery *) l->data, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
- g_object_unref (l->data);
- }
-
- g_list_free (priv->exp_queries);
- priv->exp_queries = NULL;
- }
-
g_free (priv);
gcal->priv = NULL;
}
@@ -1764,7 +1751,8 @@ client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer da
case CAL_CLIENT_OPEN_SUCCESS:
/* Set the client's default timezone, if we have one. */
if (priv->zone) {
- cal_client_set_default_timezone (client, priv->zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, priv->zone, NULL);
}
/* add the alarms for this client */
@@ -1996,7 +1984,7 @@ gnome_calendar_construct (GnomeCalendar *gcal)
/*
* TaskPad Folder Client.
*/
- priv->task_pad_client = cal_client_new ();
+ priv->task_pad_client = cal_client_new ("", CALOBJ_TYPE_TODO); /* FIXME: use default tasks */
if (!priv->task_pad_client)
return NULL;
@@ -2063,7 +2051,8 @@ gnome_calendar_get_calendar_model (GnomeCalendar *gcal)
priv = gcal->priv;
- return e_cal_view_get_model (E_CAL_VIEW (priv->week_view));
+ return e_cal_view_get_model (
+ gnome_calendar_get_current_view_widget (gcal));
}
/**
@@ -2078,6 +2067,28 @@ gnome_calendar_get_default_client (GnomeCalendar *gcal)
}
/**
+ * gnome_calendar_set_default_client
+ * @gcal: A calendar view.
+ * @client: The client to use as default.
+ *
+ * Set the default client on the given calendar view. The default calendar will
+ * be used as the default when creating events in the view.
+ */
+void
+gnome_calendar_set_default_client (GnomeCalendar *gcal, CalClient *client)
+{
+ int i;
+
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ e_cal_model_set_default_client (
+ e_cal_view_get_model (E_CAL_VIEW (gcal->priv->views[i])),
+ client);
+ }
+}
+
+/**
* gnome_calendar_get_task_pad_cal_client:
* @gcal: A calendar view.
*
@@ -2145,67 +2156,56 @@ add_alarms (const char *uri)
CORBA_exception_free (&ev);
}
+/**
+ * gnome_calendar_add_event_uri:
+ * @gcal: A GnomeCalendar.
+ * @str_uri: URI to add to the calendar views.
+ *
+ * Adds the given calendar URI to the calendar views.
+ *
+ * Returns: TRUE if successful, FALSE if error.
+ */
gboolean
-gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri)
+gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri)
{
GnomeCalendarPrivate *priv;
- gboolean success;
- EUri *uri;
- char *message;
- char *real_uri;
- char *urinopwd;
CalClient *client;
-
+ int i;
+
g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
g_return_val_if_fail (str_uri != NULL, FALSE);
priv = gcal->priv;
- g_return_val_if_fail (
- cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_NOT_LOADED,
- FALSE);
-
- uri = e_uri_new (str_uri);
- if (!uri || !g_strncasecmp (uri->protocol, "file", 4))
- real_uri = g_concat_dir_and_file (str_uri, "calendar.ics");
- else
- real_uri = g_strdup (str_uri);
-
- urinopwd = get_uri_without_password (str_uri);
- message = g_strdup_printf (_("Opening calendar at %s"), urinopwd);
- g_free (urinopwd);
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), message);
- g_free (message);
-
- client = cal_client_new ();
- g_signal_connect (G_OBJECT (client), "cal_opened", G_CALLBACK (client_cal_opened_cb), gcal);
+ client = g_hash_table_lookup (priv->clients, str_uri);
+ if (client)
+ return TRUE;
+
+ client = cal_client_new (str_uri, CALOBJ_TYPE_EVENT);
+ g_hash_table_insert (priv->clients, g_strdup (str_uri), g_object_ref (client));
+
g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal);
g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), gcal);
g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal);
- if (!cal_client_open_calendar (client, real_uri, FALSE)) {
- g_warning (G_STRLOC ": Could not issue the request to open the calendar folder");
+ if (!cal_client_open (client, FALSE, NULL)) {
+ g_hash_table_remove (priv->clients, str_uri);
g_object_unref (client);
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
return FALSE;
}
- /* Open the appropriate Tasks folder to show in the TaskPad */
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo),
- _("Opening default tasks folder"));
- success = cal_client_open_default_tasks (priv->task_pad_client, FALSE);
-
- g_free (real_uri);
- e_uri_free (uri);
-
- if (!success) {
- g_message ("gnome_calendar_open(): Could not issue the request to open the tasks folder");
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL);
- return FALSE;
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ ECalModel *model;
+
+ model = e_cal_view_get_model (priv->views[i]);
+ e_cal_model_add_client (model, client);
}
+ /* update date navigator query */
+ update_query (gcal);
+
return TRUE;
}
@@ -2308,7 +2308,8 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
CalClient *client = l->data;
if (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED)
- cal_client_set_default_timezone (client, priv->zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, priv->zone, NULL);
}
g_list_free (client_list);
@@ -2316,8 +2317,9 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
if (priv->task_pad_client
&& cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_LOADED) {
+ /* FIXME Error Checking */
cal_client_set_default_timezone (priv->task_pad_client,
- priv->zone);
+ priv->zone, NULL);
}
e_cal_view_set_timezone (E_CAL_VIEW (priv->day_view), priv->zone);
@@ -2383,147 +2385,6 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
*end_time = priv->selection_end_time;
}
-void
-gnome_calendar_edit_object (GnomeCalendar *gcal, CalClient *client, icalcomponent *icalcomp, gboolean meeting)
-{
- GnomeCalendarPrivate *priv;
- CompEditor *ce;
- const char *uid;
- CalComponent *comp;
-
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (icalcomp != NULL);
-
- priv = gcal->priv;
-
- uid = icalcomponent_get_uid (icalcomp);
-
- ce = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (!ce) {
- EventEditor *ee;
-
- ee = event_editor_new (client);
- if (!ee) {
- g_message ("gnome_calendar_edit_object(): Could not create the event editor");
- return;
- }
- ce = COMP_EDITOR (ee);
-
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
- comp_editor_edit_comp (ce, comp);
- if (meeting)
- event_editor_show_meeting (ee);
-
- e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
-
- g_object_unref (comp);
- }
-
- comp_editor_focus (ce);
-}
-
-/**
- * gnome_calendar_new_appointment_for:
- * @gcal: An Evolution calendar.
- * @dtstart: a Unix time_t that marks the beginning of the appointment.
- * @dtend: a Unix time_t that marks the end of the appointment.
- * @all_day: if true, the dtstart and dtend are expanded to cover the entire
- * day, and the event is set to TRANSPARENT.
- *
- * Opens an event editor dialog for a new appointment.
- *
- **/
-void
-gnome_calendar_new_appointment_for (GnomeCalendar *cal,
- time_t dtstart, time_t dtend,
- gboolean all_day,
- gboolean meeting)
-{
- GnomeCalendarPrivate *priv;
- struct icaltimetype itt;
- CalComponentDateTime dt;
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalComponentTransparency transparency;
- const char *category;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (cal));
-
- priv = cal->priv;
-
- dt.value = &itt;
- if (all_day)
- dt.tzid = NULL;
- else
- dt.tzid = icaltimezone_get_tzid (priv->zone);
-
- icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (priv->week_view)));
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomp);
-
- /* DTSTART, DTEND */
-
- itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
- if (all_day) {
- itt.hour = itt.minute = itt.second = 0;
- itt.is_date = TRUE;
- }
- cal_component_set_dtstart (comp, &dt);
-
- itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
- if (all_day) {
- /* We round it up to the end of the day, unless it is already
- set to midnight. */
- if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
- icaltime_adjust (&itt, 1, 0, 0, 0);
- }
- itt.hour = itt.minute = itt.second = 0;
- itt.is_date = TRUE;
- }
- cal_component_set_dtend (comp, &dt);
-
- transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
- : CAL_COMPONENT_TRANSP_OPAQUE;
- cal_component_set_transparency (comp, transparency);
-
-
- /* Category */
-
- category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar));
- cal_component_set_categories (comp, category);
-
- /* Edit! */
-
- cal_component_commit_sequence (comp);
-
- gnome_calendar_edit_object (cal, gnome_calendar_get_default_client (cal), icalcomp, meeting);
- g_object_unref (comp);
-}
-
-/**
- * gnome_calendar_new_appointment:
- * @gcal: An Evolution calendar.
- *
- * Opens an event editor dialog for a new appointment. The appointment's start
- * and end times are set to the currently selected time range in the calendar
- * views.
- **/
-void
-gnome_calendar_new_appointment (GnomeCalendar *gcal)
-{
- time_t dtstart, dtend;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (gcal, dtstart, dtend, FALSE, FALSE);
-}
-
/**
* gnome_calendar_new_task:
* @gcal: An Evolution calendar.
@@ -3020,136 +2881,17 @@ gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal)
}
}
-void
-gnome_calendar_unrecur_selection (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
- GtkWidget *view;
-
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- priv = gcal->priv;
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
-
- view = gnome_calendar_get_current_view_widget (gcal);
-
- if (E_IS_DAY_VIEW (view))
- e_day_view_unrecur_appointment (E_DAY_VIEW (view));
- else
- e_week_view_unrecur_appointment (E_WEEK_VIEW (view));
- }
-}
-
-typedef struct {
- gboolean remove;
- GnomeCalendar *gcal;
-} obj_updated_closure;
-
static gboolean
check_instance_cb (CalComponent *comp,
time_t instance_start,
time_t instance_end,
gpointer data)
{
- obj_updated_closure *closure = data;
-
- if (instance_start >= closure->gcal->priv->exp_older_than ||
- instance_end >= closure->gcal->priv->exp_older_than) {
- closure->remove = FALSE;
- return FALSE;
- }
-
- closure->remove = TRUE;
- return TRUE;
-}
-
-static void
-purging_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
- CalComponent *comp;
- icalcomponent *icalcomp;
- obj_updated_closure closure;
- gchar *msg;
-
- priv = gcal->priv;
-
- if (cal_client_get_object (cal_query_get_client (query), uid, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
- return;
-
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
- }
-
- msg = g_strdup_printf (_("Purging event %s"), uid);
-
- /* further filter the event, to check the last recurrence end date */
- if (cal_component_has_recurrences (comp)) {
- closure.remove = TRUE;
- closure.gcal = gcal;
-
- cal_recur_generate_instances (comp, priv->exp_older_than, -1,
- (CalRecurInstanceFn) check_instance_cb,
- &closure,
- (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb,
- cal_query_get_client (query), priv->zone);
-
- if (closure.remove) {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg);
- delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid),
- CAL_COMPONENT_EVENT);
- }
- } else {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg);
- delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid), CAL_COMPONENT_EVENT);
- }
-
- g_object_unref (comp);
- g_free (msg);
-}
-
-static void
-purging_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
-
- priv = gcal->priv;
-
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
-
- g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
-
- priv->exp_queries = g_list_remove (priv->exp_queries, query);
- g_object_unref (query);
-}
+ gboolean *remove = data;
-static void
-purging_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
-
- priv = gcal->priv;
-
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
+ *remove = FALSE;
- g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
-
- priv->exp_queries = g_list_remove (priv->exp_queries, query);
- g_object_unref (query);
+ return FALSE;
}
void
@@ -3163,11 +2905,6 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
priv = gcal->priv;
- /* if we have a query, we are already purging */
- if (priv->exp_queries)
- return;
-
- priv->exp_older_than = older_than;
start = isodate_from_time_t (0);
end = isodate_from_time_t (older_than);
sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")"
@@ -3177,27 +2914,47 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), _("Purging"));
+ /* FIXME Confirm expunge */
+
client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->week_view)));
for (l = client_list; l != NULL; l = l->next) {
- CalQuery *exp_query;
-
- if (cal_client_is_read_only ((CalClient *) l->data))
+ CalClient *client = l->data;
+ GList *objects, *l;
+ gboolean read_only = TRUE;
+
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (!read_only)
continue;
-
- exp_query = cal_client_get_query ((CalClient *) l->data, sexp);
- if (!exp_query) {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
- g_message ("gnome_calendar_purge(): Could not create the query");
+
+ if (!cal_client_get_object_list (client, sexp, &objects, NULL)) {
+ g_warning (G_STRLOC ": Could not get the objects");
+
continue;
}
-
- g_signal_connect (exp_query, "obj_updated", G_CALLBACK (purging_obj_updated_cb), gcal);
- g_signal_connect (exp_query, "query_done", G_CALLBACK (purging_query_done_cb), gcal);
- g_signal_connect (exp_query, "eval_error", G_CALLBACK (purging_eval_error_cb), gcal);
-
- priv->exp_queries = g_list_append (priv->exp_queries, exp_query);
+
+ for (l = objects; l; l = l->next) {
+ CalComponent *comp;
+ gboolean remove = TRUE;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data));
+
+ cal_recur_generate_instances (comp, older_than, -1,
+ (CalRecurInstanceFn) check_instance_cb,
+ &remove,
+ (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb,
+ client, priv->zone);
+
+ /* FIXME Better error handling */
+ if (remove)
+ cal_client_remove_object (client, icalcomponent_get_uid (l->data), NULL);
+
+ g_object_unref (comp);
+ }
}
+ e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
+
g_list_free (client_list);
g_free (sexp);
g_free (start);
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index c9bbcbaff4..f56ec69211 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -55,7 +55,8 @@ typedef enum {
GNOME_CAL_WORK_WEEK_VIEW,
GNOME_CAL_WEEK_VIEW,
GNOME_CAL_MONTH_VIEW,
- GNOME_CAL_LIST_VIEW
+ GNOME_CAL_LIST_VIEW,
+ GNOME_CAL_LAST_VIEW
} GnomeCalendarViewType;
typedef enum
@@ -106,9 +107,10 @@ ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal);
ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal);
CalClient *gnome_calendar_get_default_client (GnomeCalendar *gcal);
+void gnome_calendar_set_default_client (GnomeCalendar *gcal, CalClient *client);
CalClient *gnome_calendar_get_task_pad_cal_client(GnomeCalendar *gcal);
-gboolean gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri);
+gboolean gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri);
void gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp);
@@ -145,17 +147,6 @@ void gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
time_t *start_time,
time_t *end_time);
-void gnome_calendar_edit_object (GnomeCalendar *gcal,
- CalClient *client,
- icalcomponent *icalcomp,
- gboolean meeting);
-
-void gnome_calendar_new_appointment (GnomeCalendar *gcal);
-void gnome_calendar_new_appointment_for (GnomeCalendar *cal,
- time_t dtstart, time_t dtend,
- gboolean all_day,
- gboolean meeting);
-
void gnome_calendar_new_task (GnomeCalendar *gcal);
/* Returns the selected time range for the current view. Note that this may be
@@ -193,7 +184,6 @@ void gnome_calendar_paste_clipboard (GnomeCalendar *gcal);
void gnome_calendar_delete_selection (GnomeCalendar *gcal);
void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal);
-void gnome_calendar_unrecur_selection (GnomeCalendar *gcal);
void gnome_calendar_purge (GnomeCalendar *gcal,
time_t older_than);
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index f5baa8bb05..e2640f01f4 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -70,8 +70,11 @@ static EAccountList *accounts = NULL;
EAccountList *
itip_addresses_get (void)
{
- if (accounts == NULL)
- accounts = e_account_list_new(gconf_client_get_default());
+ if (accounts == NULL) {
+ GConfClient *gconf_client = gconf_client_get_default ();
+ accounts = e_account_list_new (gconf_client);
+ g_object_unref (gconf_client);
+ }
return accounts;
}
@@ -98,12 +101,14 @@ itip_organizer_is_user (CalComponent *comp, CalClient *client)
strip = itip_strip_mailto (organizer.value);
if (cal_client_get_static_capability (client, CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS)) {
- const char *email;
+ char *email;
- email = cal_client_get_cal_address (client);
- if (email && !g_strcasecmp (email, strip))
+ if (cal_client_get_cal_address (client, &email, NULL) && !g_strcasecmp (email, strip)) {
+ g_free (email);
+
return TRUE;
-
+ }
+
return FALSE;
}
@@ -185,8 +190,8 @@ foreach_tzid_callback (icalparameter *param, gpointer data)
zone = icalcomponent_get_timezone (tz_data->zones, tzid);
if (zone == NULL)
zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (zone == NULL && tz_data->client != NULL)
- cal_client_get_timezone (tz_data->client, tzid, &zone);
+ if (zone == NULL && tz_data->client != NULL)
+ cal_client_get_timezone (tz_data->client, tzid, &zone, NULL);
if (zone == NULL)
return;
@@ -528,28 +533,23 @@ static gboolean
comp_server_send (CalComponentItipMethod method, CalComponent *comp, CalClient *client,
icalcomponent *zones, GList **users)
{
- CalClientSendResult result;
- icalcomponent *top_level, *new_top_level = NULL;
- char *error_msg;
+ icalcomponent *top_level;
gboolean retval = TRUE;
+ GError *error = NULL;
top_level = comp_toplevel_with_zones (method, comp, client, zones);
- result = cal_client_send_object (client, top_level, &new_top_level, users, &error_msg);
-
- if (result == CAL_CLIENT_SEND_SUCCESS) {
- icalcomponent *ical_comp;
-
- ical_comp = icalcomponent_get_inner (new_top_level);
- icalcomponent_remove_component (new_top_level, ical_comp);
- cal_component_set_icalcomponent (comp, ical_comp);
- icalcomponent_free (new_top_level);
- } else if (result == CAL_CLIENT_SEND_BUSY) {
- e_notice (NULL, GTK_MESSAGE_ERROR, error_msg);
-
- g_free (error_msg);
- retval = FALSE;
+ if (!cal_client_send_objects (client, top_level, &error)) {
+ /* FIXME Really need a book problem status code */
+ if (error->code != E_CALENDAR_STATUS_OK) {
+ /* FIXME Better error message */
+ e_notice (NULL, GTK_MESSAGE_ERROR, "Unable to book");
+
+ retval = FALSE;
+ }
}
+ g_clear_error (&error);
+
icalcomponent_free (top_level);
return retval;
@@ -755,7 +755,8 @@ comp_compliant (CalComponentItipMethod method, CalComponent *comp, CalClient *cl
if (from_zone == NULL)
from_zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid);
if (from_zone == NULL && client != NULL)
- cal_client_get_timezone (client, dt.tzid, &from_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, dt.tzid, &from_zone, NULL);
}
to_zone = icaltimezone_get_utc_timezone ();
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
index a15c0ef846..681417f1df 100644
--- a/calendar/gui/main.c
+++ b/calendar/gui/main.c
@@ -49,9 +49,9 @@
#include "tasks-control.h"
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory"
+#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory_2"
-#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent"
+#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_Component"
#define CALENDAR_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_Control"
#define TASKS_CONTROL_ID "OAFIID:GNOME_Evolution_Tasks_Control"
#define ITIP_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_iTip_Control"
@@ -155,23 +155,19 @@ factory (BonoboGenericFactory *factory,
initialized = TRUE;
}
- if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0)
- return calendar_component_get_object ();
- if (strcmp (component_id, CALENDAR_CONTROL_ID) == 0)
+ if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0) {
+ BonoboObject *object = BONOBO_OBJECT (calendar_component_peek ());
+ bonobo_object_ref (object);
+ return object;
+ } else if (strcmp (component_id, CALENDAR_CONTROL_ID) == 0)
return BONOBO_OBJECT (control_factory_new_control ());
- if (strcmp (component_id, TASKS_CONTROL_ID) == 0)
+ else if (strcmp (component_id, TASKS_CONTROL_ID) == 0)
return BONOBO_OBJECT (tasks_control_new ());
- if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
+ else if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
return BONOBO_OBJECT (itip_bonobo_control_new ());
- if (strcmp (component_id, CONFIG_CONTROL_ID) == 0) {
- extern EvolutionShellClient *global_shell_client; /* FIXME ugly */
-
- if (global_shell_client == NULL)
- return NULL;
- else
- return BONOBO_OBJECT (cal_prefs_dialog_new ());
- }
- if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0)
+ else if (strcmp (component_id, CONFIG_CONTROL_ID) == 0)
+ return BONOBO_OBJECT (cal_prefs_dialog_new ());
+ else if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0)
return BONOBO_OBJECT (comp_editor_factory_fn ());
g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
diff --git a/calendar/gui/migration.c b/calendar/gui/migration.c
new file mode 100644
index 0000000000..be93309f1f
--- /dev/null
+++ b/calendar/gui/migration.c
@@ -0,0 +1,126 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-component.c
+ *
+ * Copyright (C) 2003 Ximian, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Rodrigo Moya <rodrigo@ximian.com>
+ */
+
+#include <bonobo/bonobo-i18n.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-xfer.h>
+#include <gal/util/e-util.h>
+#include "migration.h"
+
+static gboolean
+process_calendar_dir (ESourceGroup *source_group, const char *path,
+ const char *name, const char *base_uri)
+{
+ char *s;
+ GnomeVFSURI *from, *to;
+ GnomeVFSResult vres;
+ ESource *source;
+ GDir *dir;
+ gboolean retval = TRUE;
+
+ s = g_build_filename (path, "calendar.ics", NULL);
+ if (!g_file_test (s, G_FILE_TEST_EXISTS)) {
+ g_free (s);
+ return FALSE;
+ }
+
+ /* transfer the old file to its new location */
+ from = gnome_vfs_uri_new (s);
+ g_free (s);
+ if (!from)
+ return FALSE;
+
+ s = g_build_filename (e_source_group_peek_base_uri (source_group), base_uri,
+ "calendar.ics", NULL);
+ if (e_mkdir_hier (s, 0700) != 0) {
+ gnome_vfs_uri_unref (from);
+ g_free (s);
+ return FALSE;
+ }
+ to = gnome_vfs_uri_new (s);
+ g_free (s);
+ if (!to) {
+ gnome_vfs_uri_unref (from);
+ return FALSE;
+ }
+
+ vres = gnome_vfs_xfer_uri ((const GnomeVFSURI *) from,
+ (const GnomeVFSURI *) to,
+ GNOME_VFS_XFER_DEFAULT,
+ GNOME_VFS_XFER_ERROR_MODE_ABORT,
+ GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
+ NULL, NULL);
+ gnome_vfs_uri_unref (from);
+ gnome_vfs_uri_unref (to);
+
+ if (vres != GNOME_VFS_OK)
+ return FALSE;
+
+ /* create the new source */
+ source = e_source_new (name, base_uri);
+ e_source_group_add_source (source_group, source, -1);
+
+ /* process subfolders */
+ s = g_build_filename (path, "subfolders", NULL);
+ dir = g_dir_open (s, 0, NULL);
+ if (dir) {
+ const char *name, *tmp_s;
+
+ while ((name = g_dir_read_name (dir))) {
+ tmp_s = g_build_filename (s, name, NULL);
+ if (g_file_test (tmp_s, G_FILE_TEST_IS_DIR)) {
+ retval = process_calendar_dir (source_group, tmp_s, name, name);
+ }
+
+ g_free (tmp_s);
+ }
+
+ g_dir_close (dir);
+ }
+
+ g_free (s);
+
+ return retval;
+}
+
+gboolean
+migrate_old_calendars (ESourceGroup *source_group)
+{
+ char *path;
+ gboolean retval;
+
+ g_return_val_if_fail (E_IS_SOURCE_GROUP (source_group), FALSE);
+
+ path = g_build_filename (g_get_home_dir (), "evolution", NULL);
+ if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
+ g_free (path);
+ return FALSE;
+ }
+ g_free (path);
+
+ /* look for the top-level calendar */
+ path = g_build_filename (g_get_home_dir (), "evolution/local/Calendar", NULL);
+ retval = process_calendar_dir (source_group, path, _("Personal"), "Personal");
+ g_free (path);
+
+ return retval;
+}
diff --git a/calendar/gui/migration.h b/calendar/gui/migration.h
new file mode 100644
index 0000000000..2453d47abd
--- /dev/null
+++ b/calendar/gui/migration.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-component.c
+ *
+ * Copyright (C) 2003 Ximian, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Rodrigo Moya <rodrigo@ximian.com>
+ */
+
+#ifndef MIGRATION_H
+#define MIGRATION_H
+
+#include <e-util/e-source-group.h>
+
+gboolean migrate_old_calendars (ESourceGroup *source_group);
+
+#endif
diff --git a/calendar/gui/print.c b/calendar/gui/print.c
index 6aeb9f6566..0c0fa44886 100644
--- a/calendar/gui/print.c
+++ b/calendar/gui/print.c
@@ -522,6 +522,16 @@ format_date(time_t time, int flags, char *buffer, int bufflen)
return buffer;
}
+static gboolean
+instance_cb (CalComponent *comp, time_t instance_start, time_t instance_end, gpointer data)
+{
+ gboolean *found = data;
+
+ *found = TRUE;
+
+ return FALSE;
+}
+
/*
print out the month small, embolden any days with events.
@@ -625,16 +635,16 @@ print_month_small (GnomePrintContext *pc, GnomeCalendar *gcal, time_t month,
day = days[y * 7 + x];
if (day != 0) {
- GList *uids;
+ gboolean found = FALSE;
sprintf (buf, "%d", day);
/* this is a slow messy way to do this ... but easy ... */
- uids = cal_client_get_objects_in_range (client,
- CALOBJ_TYPE_EVENT,
- now, time_day_end_with_zone (now, zone));
- font = uids ? font_bold : font_normal;
- cal_obj_uid_list_free (uids);
+ cal_client_generate_instances (client, now, CALOBJ_TYPE_EVENT,
+ time_day_end_with_zone (now, zone),
+ instance_cb, &found);
+
+ font = found ? font_bold : font_normal;
next = time_add_day_with_zone (now, 1, zone);
if ((now >= greystart && now < greyend)
@@ -1805,7 +1815,7 @@ print_todo_details (GnomePrintContext *pc, GnomeCalendar *gcal,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- cal_component_get_summary (comp_data->icalcomp, &summary);
+ cal_component_get_summary (comp, &summary);
if (!summary.value) {
g_object_unref (comp);
continue;
@@ -2161,11 +2171,8 @@ get_zone_from_tzid (CalClient *client, const char *tzid)
the builtin timezone with the TZID first. */
zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
if (!zone) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (client, tzid, &zone);
- /* FIXME: Handle error better. */
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, tzid, &zone, NULL))
+ /* FIXME: Handle error better. */
g_warning ("Couldn't get timezone from server: %s",
tzid ? tzid : "");
}
diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c
index 03e0b3dee4..147a69f246 100644
--- a/calendar/gui/tag-calendar.c
+++ b/calendar/gui/tag-calendar.c
@@ -162,7 +162,6 @@ resolve_tzid_cb (const char *tzid, gpointer data)
{
CalClient *client;
icaltimezone *zone = NULL;
- CalClientGetStatus status;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (data), NULL);
@@ -174,7 +173,7 @@ resolve_tzid_cb (const char *tzid, gpointer data)
if (!zone) {
/* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
+ cal_client_get_timezone (client, tzid, &zone, NULL);
}
return zone;
diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c
index 5ed9faa0d6..d97ed2d585 100644
--- a/calendar/gui/tasks-control.c
+++ b/calendar/gui/tasks-control.c
@@ -235,12 +235,12 @@ static void
sensitize_commands (ETasks *tasks, BonoboControl *control, int n_selected)
{
BonoboUIComponent *uic;
- gboolean read_only;
+ gboolean read_only = TRUE;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
- read_only = cal_client_is_read_only (e_tasks_get_cal_client (tasks));
+ cal_client_is_read_only (e_tasks_get_cal_client (tasks), &read_only, NULL);
bonobo_ui_component_set_prop (uic, "/commands/TasksCut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",
diff --git a/configure.in b/configure.in
index f5338d51d5..b29fd92db0 100644
--- a/configure.in
+++ b/configure.in
@@ -1051,6 +1051,13 @@ dnl *************************
GNOME_COMPILE_WARNINGS(yes)
CFLAGS="$CFLAGS $WARN_CFLAGS"
+case $CFLAGS in
+*-Wall*)
+ # Turn off the annoying "comparison between signed and unsigned"
+ # warning in gcc 3.3
+ CFLAGS="$CFLAGS -Wno-sign-compare"
+ ;;
+esac
AM_PATH_ORBIT2
@@ -1127,7 +1134,7 @@ AC_SUBST(SHELL_LIBS)
dnl --- evolution-addressbook flags
-EVOLUTION_ADDRESSBOOK_DEPS="gconf-2.0 libbonoboui-2.0 libglade-2.0 gal-2.2 >= $GAL_REQUIRED libgnomeui-2.0 libgnome-2.0 libgnomecanvas-2.0 gnome-vfs-2.0 libgnomeprintui-2.2"
+EVOLUTION_ADDRESSBOOK_DEPS="gconf-2.0 libbonoboui-2.0 libglade-2.0 gal-2.2 >= $GAL_REQUIRED libgnomeui-2.0 libgnome-2.0 libgnomecanvas-2.0 gnome-vfs-2.0 libgnomeprintui-2.2 libgtkhtml-3.1 >= $GTKHTML_REQUIRED"
EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS)
AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@ -1331,11 +1338,15 @@ addressbook/gui/search/Makefile
addressbook/gui/widgets/Makefile
addressbook/backend/Makefile
addressbook/backend/ebook/Makefile
+addressbook/backend/ebook/tests/Makefile
+addressbook/backend/ebook/tests/ebook/Makefile
+addressbook/backend/ebook/tests/vcard/Makefile
addressbook/backend/pas/Makefile
addressbook/backend/idl/Makefile
addressbook/conduit/Makefile
addressbook/printing/Makefile
addressbook/tools/Makefile
+addressbook/util/Makefile
art/Makefile
camel/Makefile
camel/providers/Makefile
diff --git a/evolution-calendar.pc.in b/evolution-calendar.pc.in
index 755578fe91..28042a122b 100644
--- a/evolution-calendar.pc.in
+++ b/evolution-calendar.pc.in
@@ -14,4 +14,4 @@ Description: libraries needed for Evolution calendar backends
Version: @VERSION@
Requires: libgnome-2.0 libbonobo-2.0 gal-2.2 >= @GAL_REQUIRED@ gnome-vfs-2.0
Libs: -L${privlibdir} -lpcs -lcal-util -lcal-client -lical-evolution -leutil
-Cflags: -I${privincludedir}
+Cflags: -I${privincludedir} -I${privincludedir}/libical